# IEnumerable and yield return — C#/.NET

Source: https://www.skillbyai.com/en/dotnet/l-iterators

> Write lazy sequences with iterators and avoid multiple enumeration.

## Sequences produced on demand

`IEnumerable<T>` represents a sequence you can walk once from the start with an enumerator (`MoveNext()` and `Current`). An **iterator method** uses **`yield return`** to produce items one at a time; the compiler turns it into a state machine that pauses after each `yield` and resumes when the caller asks for the next item. That makes sequences **lazy**: you can model huge or even infinite data, such as lines of a large file, without loading everything. `yield break` ends the sequence. Laziness has two consequences. First, code inside the iterator, including argument validation, does not run until enumeration starts. Second, enumerating an `IEnumerable<T>` twice runs the work twice, which may hit a database or file twice or produce different results; materialise with `ToList()` when you need several passes.

## A lazy file reader

Only one line at a time is held in memory; `Take(5)` stops reading after five matches.

```cs
IEnumerable<string> ErrorLines(string path)
{
    foreach (var line in File.ReadLines(path))   // ReadLines is itself lazy
    {
        if (line.Contains("ERROR", StringComparison.Ordinal))
            yield return line;
    }
}

foreach (var line in ErrorLines("app.log").Take(5))
    Console.WriteLine(line);

IEnumerable<long> Fibonacci()
{
    long a = 0, b = 1;
    while (true)
    {
        yield return a;
        (a, b) = (b, a + b);
    }
}

var firstTen = Fibonacci().Take(10).ToList();
```

## A tap, not a bucket

A `List<T>` is a bucket of water you carry around. An iterator is a tap: water flows only while you hold your glass under it, and turning it on again runs fresh water through the pipes.

**Quiz:** Why can enumerating the same IEnumerable<T> twice be a problem?

- [ ] It never compiles
- [ ] The second enumeration is always empty
- [x] The underlying work, such as a database query or file read, may run twice
- [ ] It converts the sequence to an array

*Answer:* The underlying work, such as a database query or file read, may run twice. Lazy sequences re-execute on each enumeration unless materialised.
