Iterators and yield return
A method with yield return produces its values one at a time, pausing between them until the caller asks for the next.
Watch it animatedStep through it, with the running line highlighted. Free with an account.The idea
Calling Evens runs none of its code. Each time foreach asks for the next value, the method runs until it reaches yield return, hands over that value, and freezes with all its local variables intact.
Code
static IEnumerable<int> Evens(int max) {
for (int i = 0; i <= max; i += 2)
yield return i; // pause here and hand i to the caller
}
foreach (int n in Evens(max))
Console.Write(n);Tips
- The whole sequence never exists in memory at once, so an iterator can describe a huge or even endless sequence.
- This is how LINQ operators such as Where and Select are implemented, and why they are deferred.
In the .NET library
The compiler turns an iterator method into a hidden class that implements IEnumerator<T>, with a state field that remembers where it paused.