C# Language Lazy Evaluation


Only when the foreach statement moves to the next item does the iterator block evaluate up to the next yield statement.

Consider the following example:

private IEnumerable<int> Integers()
    var i = 0;
        Console.WriteLine("Inside iterator: " + i);
        yield return i;

private void PrintNumbers()
    var numbers = Integers().Take(3);
    Console.WriteLine("Starting iteration");

    foreach(var number in numbers)
        Console.WriteLine("Inside foreach: " + number);

This will output:

Starting iteration
Inside iterator: 0
Inside foreach: 0
Inside iterator: 1
Inside foreach: 1
Inside iterator: 2
Inside foreach: 2

View Demo

As a consequence:

  • "Starting iteration" is printed first even though the iterator method was called before the line printing it because the line Integers().Take(3); does not actually starts iteration (no call to IEnumerator.MoveNext() was made)
  • The lines printing to console alternate between the one inside the iterator method and the one inside the foreach, rather than all the ones inside the iterator method evaluating first
  • This program terminates due to the .Take() method, even though the iterator method has a while true which it never breaks out of.