3

我刚刚在互联网上找到了几个 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<string>

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 + " ");
    }
}
4

3 回答 3

4

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

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

在方法 2 中,调用只ToList计算IEnumerable一次,因此您的 SQL 查询将只运行一次。

因为您并不总是知道 IEnumerable 背后的实际内容,所以通常将强制枚举一次视为最佳实践。

于 2013-05-30T09:56:40.233 回答
0

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

foreach (var name in names)
于 2013-05-30T10:01:49.337 回答
0

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

于 2013-05-30T10:05:22.107 回答