What does the yield keyword do in C#?

C# Language Features Intermediate 2–3 Yrs3–5 Yrs Conceptual 1 min read

Quick Answer

yield return turns a method into an iterator that produces a sequence lazily — each call to MoveNext() runs the method until the next yield, then pauses, keeping its local state. It lets you stream results without building a full list in memory, and pairs with deferred LINQ.

yield return makes a method into a lazy iterator. Instead of building a list and returning it, the method runs a bit at a time — each time the consumer asks for the next item, the method resumes from where it left off, produces one value, and pauses again, remembering its locals. The practical value is streaming: I can process a million-line file one line at a time without ever holding it all in memory, and it composes with LINQ, which is also deferred. The gotcha is that nothing runs until you actually enumerate it.

  • The compiler generates a state machine implementing IEnumerator<T>.
  • The method body doesn't run at all until you start enumerating (deferred execution) — a common surprise: exceptions and side effects are delayed.
  • yield break; ends the sequence early.
  • Great for: reading a large file line by line, generating an infinite sequence, transforming a stream, avoiding a materialised intermediate list.
  • You can't use yield in a method with ref/out params, inside try/catch with a catch, or in an anonymous method.

C# — lazy line reader
public static IEnumerable<string> ReadLines(string path)
{
    using var reader = new StreamReader(path);
    string? line;
    while ((line = reader.ReadLine()) != null)
        yield return line;   // one line at a time, file stays open
}

// only reads what it needs
var firstError = ReadLines("log.txt").First(l => l.Contains("ERROR"));