【问题标题】:Iterating with IEnumerable vs List使用 IEnumerable 与 List 进行迭代
【发布时间】:2013-05-30 09:53:28
【问题描述】:

我刚刚在互联网上找到了几个 c# 代码重构示例,并偶然发现了这段特定的代码。

谁能给我解释一下,为什么Method2()会比Method1()更好?

方法 #1 - 对IEnumerable<string> 进行多次迭代

public void Method1()
{
    IEnumerable<string> names = GetNames();

    foreach (var name in names)
    {
        Console.WriteLine("Found " + name);
    }

    var allnames = new StringBuilder();

    foreach (var name in names)
    {
        allnames.Append(name + " ");
    }
}

方法 #2 - 对List&lt;string&gt; 进行多次迭代

public void Method2()
{
    IEnumerable<string> names = GetNames();

    var enumerable = names as List<string> ?? names.ToList();

    foreach (var name in enumerable)
    {
        Console.WriteLine("Found " + name);
    }

    var allnames = new StringBuilder();

    foreach (var name in enumerable)
    {
        allnames.Append(name + " ");
    }
}

【问题讨论】:

    标签: c# list refactoring iteration ienumerable


    【解决方案1】:

    因为IEnumerable 可能会进行惰性迭代。在这种情况下,迭代代码将运行两次。

    例如,如果GetNames 实际上正在与 DB 通信,则对返回的IEnumerable 进行迭代可能会执行实际的 SQL 查询。在这种情况下,在方法 1 中,您将执行该任务两次。

    在方法 2 中,对 ToList 的调用仅导致对 IEnumerable 的评估一次,因此您的 SQL 查询只会运行一次。

    由于您并不总是知道 IEnumerable 背后的实际内容,因此强制枚举仅一次通常被视为最佳实践。

    【讨论】:

    • 该示例仅适用于 c# 对象。没有涉及到 SQL 连接,这让我对重构的“力量”产生了怀疑。但正如您所说,这可能被视为最佳实践,因为您不知道 IEnumerable 背后的内容。
    【解决方案2】:

    这两种方法都擅长它的作用。唯一的区别因素是为什么我们应该使用其中一个。在第二种方法的情况下,.ToList() 调用会急切地评估表达式,从而准备 IEnumerable 集合。在第一种方法中,它只在 CLR 执行以下代码块时评估表达式。正如我所说,这取决于你想如何取得成功。

    foreach (var name in names)
    

    【讨论】:

      【解决方案3】:

      方法2更好,因为IEnumerable可能有多个枚举。

      【讨论】:

        猜你喜欢
        • 2016-02-09
        • 1970-01-01
        • 2013-11-28
        • 2014-06-25
        • 1970-01-01
        • 2012-05-07
        • 1970-01-01
        • 1970-01-01
        • 2010-09-15
        相关资源
        最近更新 更多