懶惰的評價
只有當 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
。