Эмпирические правила для того, когда назвать ToList при возврате результатов LINQ

Я ищу эмпирические правила для вызова ToList/ToArray/MemoizeAll(Rx) на IEnumerables, в противоположность возврату самого запроса при возврате IEnumerable из чего-то.

Часто я нахожу, что лучше просто возвратить запрос и позволить вызывающей стороне решить, необходим ли список или нет, но иногда это может возвратиться и укусить Вас сзади из-за ленивой природы linq.

Я хочу собрать инструкции, такие как:

Назовите ToList если:

  • Вы создаете новые объекты (например, в выборе)
  • у Вас есть побочные эффекты в Вашем запросе

Иначе возвратите запрос

10
задан 3 revs, 3 users 96% 10 July 2019 в 11:53
поделиться

5 ответов

Во-первых, у вас НИКОГДА не должно быть побочных эффектов в запросе. Это наихудшая практика. Запросы должны отвечать на вопрос, а не производить эффект.

Ответ на ваш вопрос: вернуть запрос, когда вызывающий абонент ожидает его; вернуть список, когда вызывающий абонент ожидает список. Когда вы разрабатываете свой метод, решите, что вызывающий, скорее всего, захочет, реализуйте это, а затем задокументируйте это.

Обдумывая, хочет ли вызывающий абонент запрос или список, подумайте о различиях между запросами и списками:

  • запросы всегда актуальны. Если объекты / базы данных / все, что запрашивает запрос, изменяет свое содержимое, то результаты запроса изменятся, если вы снова запустите запрос. Списки не меняют свое содержание, и поэтому списки устаревают . Если вашему абоненту требуются последние данные , то задайте ему запрос. Если им требуется снимок данных, который они могут проверить на досуге , то дайте им список.

  • выполнение запросов для получения результатов может быть дорогостоящим. Списки дешевы для получения их результатов.Если вызывающий, вероятно, захочет опросить результат много раз и ожидает каждый раз получать одни и те же результаты, дайте ему список.

  • Создание запроса быстрое . Выполнение запроса для создания списка медленное . Список всегда получает все результаты запроса. Вызывающий может захотеть дополнительно ограничить запрос, например, взяв только первые десять элементов. Если вызывающий абонент не хочет или не должен брать на себя расходы по полной итерации всего запроса, дайте ему запрос; не принимайте это решение от их имени и не давайте им список.

  • запросов крошечные . Списки большие . Многие запросы могут повторяться по n элементам в пространстве O (1); список из n элементов занимает O (n) места. Если набор результатов огромен, то включение его в список, вероятно, неэффективно.

  • и так далее.

Нет простого ответа. Ответ такой же, как и на любую другую проблему проектирования: Рассмотрите все плюсы и минусы каждого возможного решения в контексте того, что, скорее всего, хочет пользователь функции, а затем выберите разумное компромиссное решение. .

24
ответ дан 3 December 2019 в 14:42
поделиться

Вернуть ToList, если:

  • Вы не хотите или не заботитесь о ленивой оценке запросов.

Изменить:

Также верните ToList, если:

  • Вы используете какую-то среду Linq to SQL (LLBLGen, EF и т. Д.), И вам нужно выполнить операцию со списком, которая не может быть переведена в SQL фреймворком.
3
ответ дан 3 December 2019 в 14:42
поделиться

Используйте ToList, если вам нужно запускать пользовательские функции для данных, возвращаемых LINQ to SQL.

2
ответ дан 3 December 2019 в 14:42
поделиться

вы ToList () , когда вам нужен список объектов для вашего результата.

1
ответ дан 3 December 2019 в 14:42
поделиться

Используйте ToList перед выходом из блока using, в котором находится ваш DataContext.

Возвращать запрос, когда вызывающая сторона может/обязана предоставить дополнительные критерии фильтрации, которые будут использоваться индексами для уменьшения количества строк результатов и/или IO базы данных.

2
ответ дан 3 December 2019 в 14:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: