【发布时间】:2022-06-27 22:04:32
【问题描述】:
为什么Square() 在下面的代码中被再次调用?我想值正在重新计算,但为什么呢?我们之前得到了values,为什么又被调用了?为什么编译器会发出警告“Possible multiple enumeration”?
static IEnumerable<int> Square(IEnumerable<int> a)
{
foreach(var r in a)
{
Console.WriteLine($"From Square {r * r}");
yield return r * r;
}
}
class Wrap
{
private static int init = 0;
public int Value
{
get { return ++init; }
}
}
static void Main(string[] args)
{
var w = new Wrap();
var wraps = new Wrap[3];
for(int i=0; i<wraps.Length; i++)
{
wraps[i] = w;
}
var values = wraps.Select(x => x.Value);
var results = Square(values);
int sum = 0;
int count = 0;
foreach(var r in results)
{
count++;
sum += r;
}
Console.WriteLine("Count {0}", count);
Console.WriteLine("Sum {0}", sum);
Console.WriteLine("Count {0}", results.Count());
Console.WriteLine("Sum {0}", results.Sum());
}
结果:
From Square 1
From Square 4
From Square 9
Count 3
Sum 14
From Square 16
From Square 25
From Square 36
Count 3
From Square 49
From Square 64
From Square 81
Sum 194
【问题讨论】:
-
这就是
yield在 C# 中的工作原理。有很多话要说,但基本上,枚举的值或仅“按需”生成:每次调用代码“需要”一个新值时,都会创建一个新值(调用您的函数)。简单地将函数的结果分配给局部变量并不会这样做,但只有当您实际访问可枚举本身的“内容”时(“实现”它)。
标签: c# .net linq ienumerable