Зачем мне возвращать IList <T> over List <T>?

Возможный дубликат:
С# - Список <T> или IList <T>

Всюду написано, что вы должны возвращать IList<T> из своих методов, а не List<T>, но я не могу найти никаких действительно веских причин. Я продолжаю находить код, который делает это, а затем вызывающий код обычно выполняет одну из двух задач:

  • Вызовите new List<T>(returnedIList), чтобы он мог использовать все полезные методы в List
  • Возвращает к List<T>, поэтому он может использовать все полезные методы в List

Первый - неудобный, а второй - бросок (runtime) InvalidCastException, если реализация в любом случае изменится на что-то еще (что делает его абсолютно глупым).

Если я использую List<T> и по какой-то причине должен заменить его реализацией IList<T>, которую я не могу наследовать от List<T>, тогда я получу ошибки сборки и должен будет изменить некоторый код. Вероятно, это очень маловероятно, и если это произойдет, это не так много работы, чтобы исправить. Разумеется, не стоит терять преимущества List<T> и/или бросать /new List<T> (Exists, Find и т.д.), Чтобы вернуть их для этого маловероятного сценария?

Итак, существуют ли другие причины для возврата IList<T>?

Ответы

Ответ 1

Причина в том, что ваш метод можно использовать со всем, что реализует IList<T>, а не только List. Это становится еще хуже, однако, с момента появления Linq, я начал делать много вещей return Enumerable<T> или даже просто IEnumerable!

Я не уверен, что понимаю трудность. Если что-то возвращает фактический список, и его возврат зависит от этого, или его использование является специфическим для него, тогда оно должно возвращать List<T>. Если нет, тогда вам не нужно будет передавать его в список.

Ответ 2

Мне кажется, что вы смотрите на код низкого качества.

Возврат IList<T>, а не List<T> позволяет вашему коду быть более гибким. Вы можете заменить реализацию любой коллекцией, которая реализует IList<T> без нарушения кода вызова. Это хорошая вещь... но только тогда, когда функциональность, определенная в IList<T>, соответствует вашим потребностям.

Вы можете обобщить это, чтобы сказать, что вы всегда должны возвращать наиболее общий тип. В большинстве случаев вы можете уйти с IEnumerable<T>, но если вам нужно больше функциональности, то IList<T> работает. Если это не разрезает, верните конкретный тип и сделайте с ним.

В обеих ситуациях, о которых вы говорите, необходимо использовать что-то, не предоставляемое напрямую IList<T> (а если нет, то оба этих метода ошибочны). В этих случаях либо метод должен возвращать List<T> для обеспечения необходимой функциональности, либо вызывающий должен использовать другой метод.

Ответ 3

Действительно, вы должны возвращать IEnumerable, если это возможно, иначе IList.

Причина в том, что в будущем вы захотите использовать что-то другое, чем список. Это не редкость для реализации собственного списка, который реализует IList, а затем вам не нужно менять большую часть вашего кода.

Поиск производных типов из IList, и вы видите, что вы получаете много обращений только в рамках .NET Framework.

Ответ 4

Идея состоит в том, чтобы позволить вызывающему пользователю решить, какую коллекцию они будут использовать. Вы видите, что многие люди возвращаются IEnumerable<T>, когда могут. Как правило, это считается хорошей практикой. Возвращая IList, позвольте вызывающему абоненту использовать любую реализацию IList, которую они предпочитают, когда возвращать List требует, чтобы они вручную копировали данные List в свой выбор данных.

Возвращение IEnumerable идеально.