[英]How to count the items of an IEnumerable?
给定一个实例IEnumerable o
我如何获得Count项? (不列举 所有项目 )
例如,如果实例是ICollection
, ICollection<T>
和IReadOnlyCollection<T>
,则这些接口中的每个接口都有其自己的Count
方法。
通过反射获取Count
属性是唯一的方法吗?
相反,例如,我可以检查并将o
ICollection<T>
为ICollection<T>
,以便随后调用Count
吗?
无数不能保证一切。 如果是来自传感器的随机序列或实时数据馈送该怎么办? 集合的大小完全有可能是无限的。 计数它们的唯一方法是从零开始,然后为枚举器提供的每个元素递增。 LINQ正是这样做的,所以不要重新发明轮子。 LINQ非常聪明,可以使用支持此功能的集合的.Count属性。
真正涵盖集合的所有可能类型的唯一方法是使用通用接口并调用Count
方法 。 这也涵盖其他类型,例如流或仅迭代器。 此外,它会使用Count
- 财产的Count属性VS伯爵()方法? 避免不必要的开销。
但是,如果您有非通用集合,则必须使用反射来使用正确的属性。 但是,这很麻烦,如果您的集合甚至没有该属性(例如,无休止的流或只是一个迭代器),则可能会失败。 另一方面, IEnumerable<T>.Count()
将通过上述优化处理这些类型。 仅在必要时才会迭代整个集合。
如果计数不可用,这取决于您希望避免枚举项目的严重程度。
如果可以枚举项目,则可以使用LINQ方法Enumerable.Count
。 它将寻找一种快速的方法,通过将其转换为一个界面来获取项目计数。 如果不能,它将枚举。
如果要不惜一切代价避免枚举,则必须执行类型转换。 在现实生活中,您通常不必考虑所有已命名的接口,因为您通常使用其中之一( IReadOnlyCollection
很少见,而ICollection
仅在旧版代码中使用)。 如果必须考虑所有接口,请在单独的方法中尝试它们,可以将其扩展:
static class CountExtensions {
public static int? TryCount<T>(this IEnumerable<T> items) {
switch (items) {
case ICollection<T> genCollection:
return genCollection.Count;
case ICollection legacyCollection:
return legacyCollection.Count;
case IReadOnlyCollection<T> roCollection:
return roCollection.Count;
default:
return null;
}
}
}
使用以下方法访问扩展方法:
int? count = myEnumerable.TryCount();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.