C# / CHAPTER 11
Iterator methods and deferred execution
AdvancedKnow when a sequence actually performs its work.
By the end of this chapter
- Use yield return
- Trace repeated enumeration
- Materialize a stable snapshot when required
The idea
An iterator method using yield return describes how to produce a sequence one item at a time. Calling the method obtains an enumerable; its body advances as the consumer requests elements. This separates sequence construction from execution. A consumer that stops early may never reach statements after later yields.
Enumerating an ordinary iterator method again generally runs its sequence logic again. If that logic reads mutable state or performs effects, the second pass can observe different values or repeat those effects. Use ToList when the contract requires one stable materialized result, while recognizing the memory cost. Do not assume that every IEnumerable is either a stored collection or a safely repeatable external source.
using System;
using System.Collections.Generic;
using System.Linq;
static IEnumerable<int> Values() {
yield return 2;
yield return 5;
}
var snapshot = Values().ToList();
Console.WriteLine($"{snapshot.Count} {snapshot.Sum()}");2 7
ToList consumes the iterator and stores its two yielded values for later reuse.
Try it yourself
Write an iterator for nonnegative values and compare repeated enumeration with a materialized snapshot.
Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.
CHECK YOUR UNDERSTANDING