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