Подтвердить что ты не робот

Коллекция <T>, и он использует

Я наткнулся на следующий код:

var collection = new Collection<string>();

Я не видел, чтобы класс Collection использовался слишком много, и не может найти слишком много информации о его назначении. Если посмотреть на источник .NET Framework, это скорее всего оболочка вокруг списка, поскольку она хранит поле List List. Его конструктор выглядит следующим образом:

public Collection()
{
  this.items = (IList<T>) new List<T>();
}

И он также реализует IList. Таким образом, вы можете объявить коллекцию как:

IList<string> collection = new Collection<string>();

Что для меня функционально эквивалентно созданию списка вместо:

IList<string> collection = new List<string>();

Итак, когда вы когда-нибудь захотите использовать его над списком в своем собственном коде? Я вижу, что это базовый класс для других коллекций .NET, но почему они включают это как публичный конкретный (в отличие от внутреннего и/или абстрактного)?


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

  • Если вы используете в своем собственном коде, почему бы не использовать List вместо базового класса?
  • Действительно ли имеет смысл создать новую коллекцию в ваш собственный код вместо списка?
  • Если это действительно только, предоставляемый как базовый класс, почему он не абстрактный?
4b9b3361

Ответ 1

Мне не нравится отвечать на мои собственные вопросы, но, что касается третьего квартала, я считаю, что понимаю мои рассуждения. Я получил его, глядя на эту ссылку, на которую ссылается ответ Bas Paap.

Короче говоря, причина, по которой класс Collection не является абстрактным, заключается в том, что вы можете оставить себе возможность получения урока из класса на более позднюю дату. В то же время вы можете использовать его как возвращаемый тип и создавать его непосредственно. Ссылка показывает пример кода, где это так.

Я поддержал все другие ответы, которые, как я думал, затронули вопросы, поднятые в вопросе.

Ответ 2

Я думаю, что документация MSDN уже называет наиболее важные аспекты (выделенные мной):

Класс Collection предоставляет защищенные методы, которые можно использовать для  настроить его поведение при добавлении и удалении элементов, очистка коллекции или установки значения существующего элемента.

и

Примечания для разработчиков

Этот базовый класс предоставляется, чтобы облегчить для разработчиков создать пользовательскую коллекцию. Разработчикам предлагается расширить этот базовый класс, а не создавать свои собственные.

[EDIT для обновленных вопросов ypur]

1. Если вы используете в своем собственном коде, почему бы не использовать List в качестве базового класса?

Collection<T> предоставляет некоторые защищенные методы, поэтому вы можете легко override повести и полностью зарегистрировать свою собственную бизнес-логику, например:

  • ClearItems()
  • InsertItem()
  • RemoveItem()
  • SetItem()

List<T> не предоставляет их и почти не защищает методы для переопределения поведения, что затрудняет его настройку.

2. Действительно ли имеет смысл инициализировать новую коллекцию в вашем собственном коде вместо List?

Нет, не только для инициализации некоторой коллекции. Используйте его, если он вам нужен как базовый класс для реализации вашей собственной логики.

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

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

В этом случае это может помочь создать собственный тип коллекции.

Ответ 3

Класс Collection (T) является базовым классом для целой группы других классов коллекций. Класс List - это класс, оптимизированный для скорости, и класс Collection предназначен для расширяемости.

Когда вы смотрите на члены Collection(T), вы увидите, что он содержит некоторые дополнительные защищенные виртуальные методы (например, InsertItem), что класс List(T) не имеет.

Фактически, я создал экземпляр класса Collection. Я думаю, что я использовал бы этот тип только в качестве параметра в сигнатуре метода, чтобы просто не связать метод с реализацией коллекции (если это возможно).

Чтобы ответить на ваши вопросы:

  • Я бы использовал Collection(T) как базовый класс, потому что он намерение этого класса использовать в качестве базового класса для других коллекции. Он предлагает вам большую гибкость (см. Защищенный виртуальные методы InsertItem, RemoveItem и SetItem)

  • Если вам нужна коллекция, я бы использовал экземпляр List(T), так как он оптимизирован для скорости.

  • Собственно, мне интересно, почему они не сделали Collection(T) класс.

Ответ 4

Как говорит Krzysztof Cwalina :

• Список не предназначен для расширения. т.е. вы не можете переопределить какие-либо элементы. Это, например, означает, что объект, возвращающий List из свойства, не сможет получить уведомление при изменении коллекции. Коллекция позволяет вам переопределить защищенный элемент SetItem, чтобы получить "уведомление" при добавлении новых элементов или изменении существующего элемента.

• Список содержит много членов, которые не имеют большого значения во многих сценариях. Мы говорим, что List слишком "занят" для моделей общественных объектов. Представьте свойство ListView.Items, возвращающее список со всем его богатством. Теперь посмотрим на фактический тип возвращаемого ListView.Items; его путь проще и аналогичен коллекции или ReadOnlyCollection.

По этой причине в правиле FxCop CA1002 также указывается, что вы не должны открывать общие списки и вместо этого использовать Collection. См. Также эту статью о блоге команды анализа кода о правиле FxCop и почему возвращать Collection, а не List.

Итак, для вопросов 1 и 2 см. выше. Что касается третьего вопроса, то он не просто служит базовым классом. Вы должны иметь возможность создавать экземпляр и использовать его как возвращаемый тип, следовательно, это не абстрактно.

Ответ 5

Несмотря на то, что интерфейсы перечисления обеспечивают итерацию только вперед по коллекции, они не предоставляют механизм для определения размера коллекции, доступа к элементу по индексу, поиска или изменения коллекции. Для такой функциональности инфраструктура предоставляет интерфейсы ICollection, IList и IDictionary.

ICollection<T> обеспечивает среднюю функциональность (например, свойство Count).

IList<T>, а их не общий вариант обеспечивает максимальную функциональность (включая "случайный" доступ по индексу).

Редко вам понадобится реализовать любой из этих интерфейсов. Почти во всех случаях, когда вам нужно написать класс коллекции, вы можете вместо этого использовать подкласс Collection<T> и т.д.

Надеюсь, это поможет.