Почему при вызове iterator-метода с `yield return` исключение не возникает сразу, если результат не перечисляется?

Тело iterator-метода выполняется при перечислении, а не обязательно при получении IEnumerable. Поэтому исключение внутри него возникает при MoveNext/foreach, когда выполнение доходит до проблемного места.

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

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

Тело iterator-метода выполняется при перечислении, а не обязательно при получении IEnumerable. Поэтому исключение внутри него возникает при MoveNext/foreach, когда выполнение доходит до проблемного места.

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

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

Тело iterator-метода выполняется при перечислении, а не обязательно при получении IEnumerable. Поэтому исключение внутри него возникает при MoveNext/foreach, когда выполнение доходит до проблемного места.

Для немедленной проверки аргументов используют внешний обычный метод, возвращающий внутренний итератор:

IEnumerable<int> Values(int count)
{
    if (count < 0) throw new ArgumentOutOfRangeException(nameof(count));
    return Iterate();
    IEnumerable<int> Iterate()
    {
        for (int i = 0; i < count; i++) yield return i;
    }
}

Проверка count здесь происходит сразу при вызове Values, а выдача элементов остаётся ленивой. Ошибки чтения источника или вычислений внутри Iterate всё равно проявятся во время обхода.

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

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

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

Подробнее