Looking for c# Keywords? Try Ask4Keywords

C# Language Ленивая оценка


пример

Только когда оператор 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() вызов IEnumerator.MoveNext() )
  • Линии, печатающие на консоли, чередуются между тем, который находится внутри метода итератора, и внутри внутри foreach , а не все внутри метода итератора, оценивая сначала
  • Эта программа завершается из-за метода .Take() , хотя метод итератора имеет значение while true которое никогда не прерывается.