这可能是一个老问题:为什么要IEnumerable<T>继承IEnumerable?
.NET就是这样做的,但它带来了一些麻烦.每次我编写一个类实现时IEumerable<T>,我都要编写两个GetEnumerator()函数,一个用于IEnumerable<T>,另一个用于IEnumerable.
并且,IList<T>不会从IList继承.
我不知道为什么IEnumerable<T>以其他方式设计.
在.NET中,通用接口ICollection<T>具有Count属性本身.但它不会继承任何Count属性的非泛型接口.
所以,现在如果你想要确定非泛型的数量IEnumerable,你必须检查它是否正在实现ICollection,如果没有,你必须使用反射来查找它是否实现泛型ICollection<X>,因为你不知道泛型参数X.
如果ICollection<T>不能直接从中继承ICollection,为什么不存在另一个Count只具有属性的非泛型接口?
这只是糟糕的设计选择吗?
更新:为了使问题更清楚,我在当前的实现中演示了这个问题:
static int? FastCountOrZero(this IEnumerable items)
{
if (items == null)
return 0;
var collection = items as ICollection;
if (collection != null)
return collection.Count;
var source = items as IQueryable;
if (source != null)
return QueryableEx.Count(source);
// TODO process generic ICollection<> - I think it is not possible without using reflection
return items.Cast<object>().Count();
}
Run Code Online (Sandbox Code Playgroud) 我将编写一个库来遍历一个对象图(就像某种序列化一样).
您将需要判断一个对象是否是遍历中的集合,因此ICollection我的想法就出现了.(string也已实施IEnumerable)
但是,ICollection除了HashSet仅实施之外,几乎集合中的所有容器都已实现,这真的很奇怪ICollection<T>......
我检查了System.Collections命名空间中的几乎所有常见容器:
ArrayList : IList, ICollection, IEnumerable, ICloneable
BitArray : ICollection, IEnumerable, ICloneable
Hashtable : IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback, ICloneable
Queue : ICollection, IEnumerable, ICloneable
SortedList : IDictionary, ICollection, IEnumerable, ICloneable
Stack : ICollection, IEnumerable, ICloneable
Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, ISerializable, IDeserializationCallback
HashSet<T> : ISerializable, IDeserializationCallback, ISet<T>, ICollection<T>, IEnumerable<T>, IEnumerable
LinkedList<T> …Run Code Online (Sandbox Code Playgroud)