C#: разница между списком и коллекцией (CA1002, не предоставлять общие списки) [дубликат]


этот вопрос уже есть ответ здесь:

  • Коллекция против списка что вы должны использовать на своих интерфейсах? 8 ответов

попытался запустить анализ кода запуска в проекте здесь, и получил ряд предупреждений, которые говорили что-то вроде этого:

CA1002: Microsoft.конструктивное изменение СписокSomeType > 'in'SomeClass.SomeProtectedOrPublicProperty ' использовать Collection, ReadOnlyCollection или KeyedCollection

почему я должен использовать Collection<T> вместо List<T>? Когда я смотрю на документацию msdn, они кажутся почти равными. Прочитав справку об ошибке для предупреждения, я обнаружил, что

.Коллекции.Родовой.List (T) _ является общей коллекцией, предназначенной для производительности, а не наследования и, следовательно, не содержит никаких виртуальных членов.

что это значит? И что я должен делать вместо этого?

Я должен продолжать использовать List<T> внутренне, а затем в свойствах возвращает a ? Или я должен просто начать использовать Collection<T> вместо List<T>?

2 93

2 ответа:

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

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

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

Collection предоставляет некоторые виртуальные элементы (insert, remove, set, clear), которые можно переопределить и предоставить дополнительные функции (например, события уведомлений) при изменении коллекции.

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

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