Почему не делает ICollection <T>, реализуют ICollection? [дубликат]

29
задан BlueRaja - Danny Pflughoeft 15 July 2013 в 21:08
поделиться

3 ответа

Как сказал Ник, ICollection практически бесполезен.

Эти интерфейсы похожи только названием, CopyTo и Count - единственные общие свойства. Add, Remove, Clear, Contains и IsReadOnly были добавлены, а IsSychronized и SyncRoot были удалены.

По сути, ICollection - мутабельный, ICollection - нет.

Krzysztof Cwalina имеет больше информации на эту тему

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

10
ответ дан 28 November 2019 в 02:07
поделиться

Во-первых, IList не реализует IList , вероятно, для по тем же причинам. IList реализует: ICollection , IEnumerable , IEnumerable

Некоторые части ICollection просто не нужны, но изменение интерфейса после того, как он вышел в дикой природе, ломка в лучшем случае.

Посмотрите на ICollection:

public interface ICollection : IEnumerable
{
    void CopyTo(Array array, int index);

    int Count { get; }
    bool IsSynchronized { get; }
    object SyncRoot { get; }
}

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

4
ответ дан 28 November 2019 в 02:07
поделиться

И ICollection, и ICollection содержат по крайней мере один метод, возвращающий тип коллекции (GetEnumerator), и другой, принимающий его в качестве аргумента (CopyTo).

ICollection.GetEnumerator ковариантен с ICollection.GetEnumerator, потому что T - более конкретный тип, чем System.Object. Эта часть в порядке. Именно поэтому IEnumerable может быть подклассом (и таким образом быть заменяемым) для IEnumerable.

Но если мы хотим, чтобы ICollection была заменяемой для ICollection, нам также нужно, чтобы ICollection.CopyTo была контравариантна ICollection.CopyTo, а это не так. Метод ICollection.CopyTo не может принимать параметр типа меньше, чем T (грамматика generics ограничивает его значением T или меньше). И если метод ICollection.CopyTo не является контравариантным по своему аргументу, то это означает, что интерфейс ICollection в целом не заменяем на ICollection.

Это может быть немного трудно понять; это сложнее, потому что имеет дело с массивами. Это ослепительно очевидно в IList, где реализация обоих интерфейсов потенциально может нарушить безопасность типов, которая должна быть гарантирована дженериками (просто вызывая недженерический метод IList.Add). Но на самом деле это просто другой способ сказать, что метод IList.Add не является контравариантным в своих аргументах с IList.Add - родовой метод не может принять в качестве аргумента менее специфичный тип System.Object.

Короче говоря: ICollection просто не может быть заменен на ICollection при любых обстоятельствах, и поэтому не может наследоваться от него.

0
ответ дан 28 November 2019 в 02:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: