LINQには、列挙型をカウントする2つの方法、Count
およびLongCount
があります。実際には、これらの2つの唯一の違いは、最初はint
を返し、2番目はlong
を返します。LINQのLongCount拡張メソッドが追加された実用的な理由はありますか?
2番目の方法が追加された理由は不明です。唯一のユースケースは2B以上の要素の列挙型を処理することだと思われます。これは、いくつかの理由のために、私には貧しい意思決定のように思える:
ほとんどBCLコレクションは
int
に収まるように保証されている長さを有している単一次元配列によって支えられています。それを過ぎようとするとOverflowException
/OutOfMemoryException
が発生します。LongCount
はIEnumerable
が遅延であるためO(n)です。 3B要素を列挙できる場合は、LongCount
を呼び出してから、もう一度繰り返します(値を使用する必要がある場合)。余分な3B繰り返しを追加します。非常に遅く、開発者から隠れてしまいます。ToArray
/ToList
のような他のLINQ演算では、(1)のために2B +要素の列挙型をサポートしません。
私はここに何かがないか、もっと具体的な理由はLongCount
が追加されましたか?ありがとう。
ソースコード 'LongCount'に基づいて' Enumerator.MoveNext'で 'IEnumerable'を繰り返し、' Count'は 'ICollection'に' IEnumerable'をキャストしようとし、キャストが失敗した場合は 'Count'を使って反復します'IEnumerable'と同じ方法で' LongCount'を呼び出します。 [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'はそれほど使われないので、そうしていないのです。 –