使用IEnumerable和List进行迭代
本文关键字:迭代 List IEnumerable 使用 | 更新日期: 2023-09-27 18:16:07
我刚刚在网上找到了一些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 + " ");
}
}
因为IEnumerable
可能做延迟迭代。在这种情况下,迭代代码将运行两次。
例如,如果GetNames
实际上正在与DB通信,那么迭代返回的IEnumerable
可能会执行实际的SQL查询。在这种情况下,在方法1中,您将执行该任务两次。
在方法2中,对ToList
的调用只导致IEnumerable
的求值一次,因此您的SQL查询只运行一次。
因为你并不总是知道IEnumerable的背后是什么,所以最好的做法是只强制枚举一次。
这两种方法都很好。唯一的区别是为什么我们应该使用其中一个。对于第二个方法,. tolist()调用急切地求值表达式,它准备IEnumerable集合。在第一个方法中,它只在CLR执行以下代码块时计算表达式。正如我所说,这取决于你想如何取得成功。
foreach (var name in names)
方法2更好,因为IEnumerable可能有多个枚举。