Как работает оператор yield в C#

В C# оператор yield используется для упрощенного создания итераторов, позволяя методам возвращать элементы последовательности по мере их генерации без необходимости создания вспомогательных коллекций.

Как работает yield

Оператор yield используется в методах, которые возвращают IEnumerable<T> или IEnumerator<T>. Он позволяет сохранять состояние метода между вызовами, что делает его удобным для ленивой генерации данных.

Пример использования yield return:

public static IEnumerable<int> GetNumbers()
{
    for (int i = 1; i <= 3; i++)
    {
        yield return i;
    }
}

Здесь метод GetNumbers() не возвращает сразу всю коллекцию, а поочередно отдает элементы при каждом вызове MoveNext().

yield break

Оператор yield break позволяет досрочно завершить генерацию последовательности.

public static IEnumerable<int> GetNumbers(int max)
{
    for (int i = 1; i <= max; i++)
    {
        if (i > 5) yield break;
        yield return i;
    }
}

В этом примере итератор завершает выполнение, если i становится больше 5.

Как yield работает под капотом

При компиляции метода с yield return компилятор создает скрытую реализацию IEnumerable<T> и IEnumerator<T>, позволяя сохранять состояние между вызовами. Это делает yield удобным для работы с потоками данных, например, чтения файлов или обработки запросов.

Преимущества yield

  1. Экономия памяти – данные генерируются по мере запроса, без необходимости хранения всей коллекции в памяти.
  2. Читаемость кода – избавляет от необходимости вручную реализовывать IEnumerator<T>.
  3. Ленивое выполнение – элементы создаются только при необходимости, а не заранее.

Оператор yield упрощает создание итераторов, позволяя эффективно работать с последовательностями данных. Он особенно полезен при обработке больших объемов данных или потоковом вводе-выводе.