IEnumerable<T> реализует IEnumerable.
Но ICollection<T> не реализует ICollection.
Каково было обоснование этого и/или было ли это просто надзором?
IEnumerable<T> реализует IEnumerable.
Но ICollection<T> не реализует ICollection.
Каково было обоснование этого и/или было ли это просто надзором?
Как сказал Ник, ICollection почти бесполезен.
Эти интерфейсы похожи только на их имя, CopyTo и Count - единственные общие свойства. Add, Remove, Clear, Contains и IsReadOnly были добавлены, а IsSychronized и SyncRoot были удалены.
По существу, ICollection<T> является изменяемым, ICollection не является.
Krzysztof Cwalina имеет больше на этой теме
ICollection<T>выглядит какICollection, но на самом деле это совсем другая абстракция. Мы обнаружили, чтоICollectionне очень полезен. В то же время у нас не было абстракции, которая представляла собой неиндексированную коллекцию чтения/записи.ICollection<T>является такой абстракцией, и вы можете сказать, чтоICollectionне имеет точного соответствующего партнера в родовом мире;IEnumerable<T>является самым близким.
ICollection<T> и ICollection на самом деле очень разные интерфейсы, к которым, к сожалению, принадлежит имя и не более того.
Из http://blogs.msdn.com/b/kcwalina/archive/2005/09/23/collections.aspx
ICollection<T>выглядит какICollection, но на самом деле это совсем другая абстракция. Мы обнаружили, чтоICollectionне очень полезен. В то же время у нас не было абстракции, которая представляла собой неиндексированную коллекцию чтения/записи.ICollection<T>- такая абстракция, и вы могли бы сказать, чтоICollectionне имеет точного соответствующего партнера в родовом мире;IEnumerable<T>является самым близким.
Во-первых, IList<T> выполняет не реализацию IList, возможно, по тем же причинам. IList<T> реализует: ICollection<T>, IEnumerable<T>, IEnumerable
Некоторые части ICollection просто не нужны, но изменение интерфейса после него в дикой природе в лучшем случае прерывается.
Посмотрите на ICollection:
public interface ICollection : IEnumerable
{
void CopyTo(Array array, int index);
int Count { get; }
bool IsSynchronized { get; }
object SyncRoot { get; }
}
Это просто не свойства, которые вам нужны в большинстве случаев, когда мне нужна коллекция, которую я никогда не нуждался в этом, и не хотел бы ее реализовывать. Похоже, это было рассуждение, но я должен попросить команду .Net утвердительного ответа.
Оба ICollection и ICollection<T> содержат по крайней мере один метод, который возвращает тип коллекции (GetEnumerator), а другой - как аргумент (CopyTo).
ICollection<T>.GetEnumerator ковариантно с ICollection.GetEnumerator, потому что T является более конкретным типом, чем System.Object. Эта часть в порядке. Вот почему IEnumerable<T> может подкласса (и, следовательно, быть подставляемым) для IEnumerable.
Но если мы хотим, чтобы ICollection<T> была подставляемой для ICollection, нам также нужно, чтобы ICollection<T>.CopyTo была контравариантна с ICollection.CopyTo, а это не так. Метод ICollection<T>.CopyTo не может принимать параметр менее специфического типа, чем T (грамматика дженериков ограничивает его T или меньше). И если метод ICollection<T>.CopyTo не является контравариантным в своем аргументе, то это означает, что интерфейс ICollection<T> в целом не подлежит замене для ICollection.
Это может быть немного трудно понять; это сложнее, потому что речь идет о массивах. Это ослепительно очевидно в IList<T>, где реализация обоих интерфейсов может потенциально нарушить безопасность типа, которая должна быть гарантирована генериками (путем простого вызова метода non-generic IList.Add). Но это просто еще один способ сказать, что метод IList<T>.Add не является контравариантным в своих аргументах с IList.Add - общий метод не может принять менее специфический тип System.Object в качестве аргумента.
Короче говоря: ICollection<T> просто не может быть заменен на ICollection при любых обстоятельствах и поэтому не может наследовать его.