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;
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);
}
}
This will output:
Starting iteration
Inside iterator: 0
Inside foreach: 0
Inside iterator: 1
Inside foreach: 1
Inside iterator: 2
Inside foreach: 2
As a consequence:
Integers().Take(3);
does not actually starts iteration (no call to IEnumerator.MoveNext()
was made)foreach
, rather than all the ones inside the iterator method evaluating first.Take()
method, even though the iterator method has a while true
which it never breaks out of.