LINQ有两种计算枚举数的方法:Count
和LongCount
。实际上,这两者之间的唯一区别是第一个返回int
,而第二个返回long
。为什么添加LINQ的LongCount扩展方法有实际的理由吗?
我不清楚为什么添加第二种方法。看起来它唯一的用例是处理超过2B个元素的枚举。这似乎是一个错误的决定对我来说,有几个原因:
大多数BCL藏品是由一维数组,其具有保证,以适应在
int
长度的支持。试图通过这将提高OverflowException
/OutOfMemoryException
。LongCount
是O(n),因为IEnumerable
是懒惰的。如果你有一个可枚举的3B元素,你可以调用LongCount
,然后再次遍历它(如果你想使用任何值,你将不得不这样做),你将会增加额外的3B迭代,这将是非常缓慢,并且从开发者那里隐藏起来。由于(1),其他LINQ操作(如
ToArray
/ToList
)不支持具有2B +元素的枚举类型。
我在这里错过了一些东西,还是有更实际的原因为什么LongCount
被添加?谢谢。
基于源代码'LongCount'只是通过'Enumerator.MoveNext'遍历IEnumerable',而'Count'试图将'IEnumerable'强制转换为'ICollection'并且使用它的'Count'如果cast不成功,它将迭代'与'LongCount'相同的方式'IEnumerable'。 [https://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,d76b4b5d3fd67767](https://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs, d76b4b5d3fd67767)。基于@EricLipert的这个“猜测”似乎很合逻辑 – Fabio
@Fabio,这只是一个优化。对于'LongCount'来说''ICollection'也是在语义上是正确的,并且只将结果转换为'long',但'LongCount'没有被使用太多,所以这就是为什么他们没有这么做。 –