Выбор ответа Middle Коллекции и LINQ обновлено

Повторное перечисление IEnumerable

Вопрос

Метод получает IEnumerable<Order> orders, построенный из LINQ-запроса с тяжёлым Select. Внутри вызываются orders.Any(), затем orders.Count() и foreach. В чём проблема?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Запрос выполнится трижды: каждый вызов перечисляет заново. LINQ-запрос не хранит результат, каждое перечисление выполняет цепочку заново: тяжёлый Select (или запрос к БД) отработает три раза.

Варианты ответа

  1. Запрос выполнится трижды: каждый вызов перечисляет зановоправильный ответ
  2. Никакой: результат LINQ кешируется после первого перечисления
  3. Count() бросит исключение, так как последовательность прочитана
  4. Any() заблокирует последовательность для других потоков

Разбор

LINQ-запрос не хранит результат, каждое перечисление выполняет цепочку заново: тяжёлый Select (или запрос к БД) отработает три раза. Кеширования нет. Обычный LINQ to Objects можно перечислять повторно без исключений, но некоторые источники (потоки, yield по сети) дадут другой результат или ошибку. Решение: материализовать один раз через ToList() или принимать IReadOnlyCollection<T>.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.