Чтобы ответить на вопрос «почему» относительно того, почему бы не List<T>
, причины этого - будущее и простота API.
Future корректуры
List<T>
не предназначен для легкого расширения с помощью его подкласса; это разработано, чтобы быть быстрым для внутренних реализаций. Вы заметите, что методы на нем не являются виртуальными и поэтому не могут быть переопределены, и нет никаких хуков для его операций Add
/ Insert
/ Remove
.
Это означает, что если вам необходимо изменить поведение коллекции в будущем (например, отклонить нулевые объекты, которые люди пытаются добавить, или выполнить дополнительную работу, когда это происходит, например, обновить состояние вашего класса), то вам необходимо измените тип коллекции, которую вы вернете, на ту, которую вы можете создать в подклассе, что будет серьезным изменением интерфейса (конечно, изменение семантики таких вещей, как недопущение нулевого значения, также может быть изменением интерфейса, но такие вещи, как обновление состояния внутреннего класса, не ).
Таким образом, возвращая либо класс, который можно легко разделить на подклассы, например Collection<T>
, либо интерфейс, такой как IList<T>
, ICollection<T>
или IEnumerable<T>
, вы можете изменить внутреннюю реализацию на другой тип коллекции, соответствующий вашим необходимо, не нарушая код потребителей, потому что он все еще может быть возвращен как ожидаемый тип.
API Простота
List<T>
содержит много полезных операций, таких как BinarySearch
, Sort
и так далее. Однако, если вы представляете эту коллекцию, скорее всего, вы контролируете семантику списка, а не потребителей. Поэтому, хотя вашему классу могут понадобиться эти операции внутри организации, очень маловероятно, что потребители вашего класса захотят (или даже должны) вызвать их.
Таким образом, предлагая более простой класс коллекции или интерфейс, вы уменьшаете количество элементов, которые видят пользователи вашего API, и упрощаете их использование.