在Visual Studio中,ReSharper警告:"可能多次枚举IEnumerable",代码如下:
static void Main(string[] args)
{
IEnumerable<string> items = Test2();
foreach (var item in items)
{
Console.WriteLine(item);
}
var newitems = new StringBuilder();
foreach (var item in items)
{
newitems.Append(item);
}
}
private static IEnumerable<string> Test2()
{
string[] array1 = { "1", "2", "3" };
return array1;
}
Run Code Online (Sandbox Code Playgroud)
我希望Test2方法将被调用两次,但它被调用一次.
我错过了什么?
它只被调用一次因为Test2()实际返回string []也是一个IEnumerable<string>.
这个string []数组仍然被引用,items因此每次使用 items时只需重新使用数组.
您期望的情况是Test2()使用迭代器块的实现:
private static IEnumerable<string> Test2()
{
string[] array1 = { "1", "2", "3" };
foreach (var str in array1)
{
yield return str;
}
}
Run Code Online (Sandbox Code Playgroud)
看看这个例子:
void Main()
{
IEnumerable<int> items = Test2();
foreach (var item in items)
{
Console.WriteLine(item);
}
var newitems = new StringBuilder();
foreach (var item in items)
{
newitems.Append(item);
}
}
IEnumerable<int> Test2()
{
Console.WriteLine("Test2 called");
return GetEnum();
}
IEnumerable<int> GetEnum()
{
for(var i = 0; i < 5; i ++)
{
Console.WriteLine("Doing work...");
Thread.Sleep(50); //Download some information from a website, or from a database
yield return i;
}
}
Run Code Online (Sandbox Code Playgroud)
试想一下,return GetEnum();是return new int[] { 1, 2, 3 }
现在,对于数组,多次迭代它们并不一定是件坏事.在你的情况下,你可以在一个循环中完成工作,但这不是resharper警告你的原因.它警告你,因为有可能Test2()返回一个懒惰的枚举,每次迭代时它都能正常工作.
如果您运行上面的代码,您将获得此输出:
Test2 called
Doing work...
0
Doing work...
1
Doing work...
2
Doing work...
3
Doing work...
4
Doing work...
Doing work...
Doing work...
Doing work...
Doing work...
Run Code Online (Sandbox Code Playgroud)
请注意,Test2它本身只被调用一次,但是枚举被迭代两次(并且工作完成了两次!).
你可以通过写:
var items = Test2().ToList();
Run Code Online (Sandbox Code Playgroud)
这将立即评估可枚举并将其放入列表中.在这种情况下,工作只进行一次.
| 归档时间: |
|
| 查看次数: |
208 次 |
| 最近记录: |