懶惰的評價

只有當 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