Разбор поведения итератора с оператором yield в C#

Последовательность содержит только 1. После окончания перечисления Current читать нельзя по контракту; с обычным сгенерированным C#-итератором здесь можно увидеть сохранённую 1.

Короткий ответ

Что ответить на собеседовании

Последовательность содержит только 1. После окончания перечисления Current читать нельзя по контракту; с обычным сгенерированным C#-итератором здесь можно увидеть сохранённую 1.

Подробный разбор

Ответ с пояснениями

Условие

Определите, какой вывод получит программа при выполнении следующего кода.

var start = 0;
var iterator = GenerateSequence(start);

static IEnumerator<int> GenerateSequence(int start)
{
    if (start % 2 != 0)
    {
        yield break;
    }

    if (start < 3)
    {
        start++;
        yield return start;
    }
}

iterator.MoveNext();
iterator.MoveNext();
iterator.MoveNext();
Console.WriteLine(iterator.Current);

Ответ

Последовательность содержит только 1. После окончания перечисления Current читать нельзя по контракту; с обычным сгенерированным C#-итератором здесь можно увидеть сохранённую 1.

Первый MoveNext доходит до yield return, возвращает true и устанавливает Current = 1. Второй продолжает выполнение после yield и достигает конца метода, возвращая false. Третий также возвращает false: цикла, который генерировал бы 2 и 3, в функции нет.

Надёжное использование: while (iterator.MoveNext()) Console.WriteLine(iterator.Current);. После false значение Current не определено контрактом IEnumerator, поэтому наблюдаемое сохранённое значение не следует считать общей гарантией итераторов.

Источник: learn.microsoft.com.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее