我想做的,简短的版本:
var source = new[]{2,4,6,1,9}.OrderBy(x=>x);
int count = source.Count; // <-- get the number of elements without performing the sort
长版:
要确定IEnumerable中的元素数量,必须遍历所有元素。这可能是一项非常昂贵的操作。
如果可以将IEnumerable 强制转换为ICollection,则无需迭代即可快速确定计数。LINQ Count() 方法自动执行此操作。
函数myEnumerable.OrderBy()返回一个IOrderedEnumerable。IOrderedEnumerable显然不能强制转换为ICollection ,因此调用Count()将消耗整个事情。
但是排序不会改变元素的数量,并且IOrderedEnumerable必须保留对其源的引用。因此,如果该源是ICollection,则应该可以从IOrderedEnumerable确定计数而不使用它。
我的目标是有一个库方法,它采用带有 n 个元素的IEnumerable,然后例如检索位置 n/2 处的元素;
我想避免迭代IEnumerable两次以获取其计数,但我也想尽可能避免创建不必要的副本。
这是我要创建的功能的骨架
public void DoSomething(IEnumerable<T> source)
{
int count; // What we do with the source depends on its length
if (source is ICollection)
{
count = source.Count(); // Great, we can use ICollection.Count
}
else if (source is IOrderedEnumerable)
{
// TODO: Find out whether this is based on an ICollection,
// TODO: then determine the count of that ICollection
}
else
{
// Iterating over the source may be expensive,
// to avoid iterating twice, make a copy of the source
source = source.ToList();
count = source.Count();
}
// do some stuff
}