С#: Почему Microsoft не сделала наследование ReadOnlyCollection <T> с ReadOnlyCollectionBase?

Проще говоря, Microsoft определила ReadOnlyCollectionBase, но не использовала его в качестве базового класса для ReadOnlyCollection<T>, когда ясно звучит, что это должно было быть так.

Я что-то упустил? Я имею в виду, была ли веская причина для NOT сделать этот класс базовым классом?

Ответ 1

Вероятно, потому что он не является общим и реализует ICollection, тогда как ReadOnlyCollection<T> является общим и реализует ICollection<T>. Обратите внимание, что ICollection<T> не реализует ICollection. На этом topic:

ICollection<T> выглядит как ICollection, но на самом деле это совсем другая абстракция. Мы обнаружили, что ICollection не очень полезен. В то же время у нас не было абстракции, которая представляла собой неиндексированную коллекцию чтения/записи. ICollection<T> - такая абстракция, и вы могли бы сказать, что ICollection не имеет точного соответствующего партнера в родовом мире; IEnumerable<T> является самым близким.

Из этого же сообщения:

ReadOnlyCollection<T> намного лучше ReadOnlyCollectionBase. Его в пространстве имен System.Collections.ObjectModel.

Фактически, ReadOnlyCollection<T> есть ReadOnlyCollectionBase в пространстве generics.

Обратите внимание, что IList<T> не реализует IList.

В общем случае классы pre-generics не служат полезными абстракциями для общих классов (за исключением IEnumerable).

Ответ 2

Если вы посмотрите на историю .net framework, вы найдете дженерики с 2.0, но ReadOnlyCollectionBase уже в 1.1. Причина не выбора ReadOnlyCollectionBase проста - она ​​не является общей, в то время как цель ReadOnlyCollection<T> должна быть общей. Таким образом, он нуждается в значительно другом дереве наследования.

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

Ответ 4

Наследование из не общего базового класса будет неэффективным. Если тип использовал неосновную базу, все это было бы тонким слоем над базовой коллекцией, где общие функции просто получались бы из кастинга из базовых object экземпляров базовой коллекции.

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