懒惰的评价
只有当 foreach
语句移动到下一个项时,迭代器块才会计算到下一个 yield
语句。
请考虑以下示例:
private IEnumerable<int> Integers()
{
var i = 0;
while(true)
{
Console.WriteLine("Inside iterator: " + i);
yield return i;
i++;
}
}
private void PrintNumbers()
{
var numbers = Integers().Take(3);
Console.WriteLine("Starting iteration");
foreach(var number in numbers)
{
Console.WriteLine("Inside foreach: " + number);
}
}
这将输出:
开始迭代迭代
器内部:0
内部 foreach:0
内部迭代器:1
内部 foreach:1
内部迭代器:2
内部 foreach:2
作为结果:
- 首先打印开始迭代,即使在行打印之前调用迭代器方法,因为行
Integers().Take(3);
实际上没有开始迭代(没有调用IEnumerator.MoveNext()
) - 打印到控制台的行在迭代器方法内部和
foreach
内部的行之间交替,而不是迭代器方法内部的所有行首先评估 - 这个程序由于
.Take()
方法而终止,即使迭代器方法有一个从未打破过的while true
。