IEnumerable<T>
实施IEnumerable
但ICollection<T>
未实现ICollection
。
这是什么理由和/或只是一种疏忽?
答案 0 :(得分:10)
正如尼克所说,ICollection
几乎没用。
这些界面仅与其名称相似,CopyTo
和Count
是唯一的共同属性。在Add
和Remove
被删除后添加了Clear
,Contains
,IsReadOnly
,IsSychronized
和SyncRoot
。
实质上,ICollection<T>
是可变的,ICollection
不是。
ICollection<T>
似乎是ICollection
,但它实际上是一个非常不同的抽象。我们发现ICollection
不是很有用。同时,我们没有表示读/写非索引集合的抽象。ICollection<T>
是这样的抽象,你可以说ICollection
在通用世界中没有完全对应的对等体;IEnumerable<T>
是最接近的。
答案 1 :(得分:6)
ICollection<T>
和ICollection
实际上是非常不同的界面,不幸的是,它们共享一个名称而不是其他。
来自http://blogs.msdn.com/b/kcwalina/archive/2005/09/23/collections.aspx
ICollection<T>
似乎是ICollection
,但它实际上是一个非常不同的抽象。我们发现ICollection
不是很有用。同时,我们没有表示读/写非索引集合的抽象。ICollection<T>
是这样的抽象,你可以说ICollection
在通用世界中没有完全对应的对等体;IEnumerable<T>
是最接近的。
答案 2 :(得分:4)
首先,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团队给出肯定的答案。
答案 3 :(得分:0)
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>
。
这可能有点难以理解;它更复杂,因为它处理数组。它在IList.Add
中显而易见,其中实现两个接口可能会破坏泛型保证的类型安全性(通过简单地调用非泛型IList<T>.Add
方法)。但这实际上只是另一种说法IList.Add
方法在其System.Object
参数中不具有逆变性的方式 - 泛型方法不能接受特定于较少类型的ICollection<T>
作为参数。
长话短说:ICollection
在任何情况下都不能替代{{1}},因此不能从中继承。