CountプロパティとCount()メソッド?


85

コレクションの操作には、オブジェクトの数を取得する2つの方法があります。Count(プロパティ)とCount()(メソッド)。主な違いが何であるか誰かが知っていますか?

私は間違っているかもしれませんがCountCount()メソッドがコレクションに対して何らかのクエリを実行すると想定しているため、条件ステートメントでは常にプロパティを使用します。これは、Count「取得」する前にすでに割り当てられている必要があります。しかし、それは推測です-私が間違っているとパフォーマンスが影響を受けるかどうかはわかりません。

編集:好奇心から、Count()コレクションがnullの場合、例外がスローされますか?Countプロパティが単に0を返すと確信しているからです。


7
どちらもnullの.何かに演算子を適用しようとしているため、どちらもnullコレクションの例外をスローします。
AaronLS 2012年

回答:


109

Count()拡張メソッドのソースを逆コンパイルすると、オブジェクトがICollection(汎用またはその他)であるかどうかをテストし、そうである場合は、基になるCountプロパティを返すだけであることがわかります。

したがって、コードがCountを呼び出す代わりにアクセスするCount()場合は、型チェックをバイパスできます。理論的なパフォーマンス上の利点ですが、目立つものになるとは思えません。

// System.Linq.Enumerable
public static int Count<TSource>(this IEnumerable<TSource> source)
{
    checked
    {
        if (source == null)
        {
            throw Error.ArgumentNull("source");
        }
        ICollection<TSource> collection = source as ICollection<TSource>;
        if (collection != null)
        {
            return collection.Count;
        }
        ICollection collection2 = source as ICollection;
        if (collection2 != null)
        {
            return collection2.Count;
        }
        int num = 0;
        using (IEnumerator<TSource> enumerator = source.GetEnumerator())
        {
            while (enumerator.MoveNext())
            {
                num++;
            }
        }
        return num;
    }
}

10
これをリバースエンジニアリングするイニシアチブを取るための+1、非常に役立ちます。
多項式2011年

7
ただし、3.5Count()では非ジェネリックICollectionインターフェイスをチェックしないことに注意してください。これは.NET4でのみ追加されました。3.5と4の両方が汎用ICollection<T>インターフェースをチェックします。
thecoop 2011年

2
要素のないシーケンスでcountを呼び出すと、例外がスローされます。ただし、Count()は正常に機能します。
amesh 2013

33

パフォーマンスは、どちらかを選択する唯一の理由です。選択.Count()すると、コードがより一般的になります。コレクションを生成しなくなったコードをリファクタリングし、代わりにIEnumerableのようなより一般的なものをリファクタリングしたことがありますが、依存していたために他のコードが壊れてしまい、.Countに変更する必要がありました.Count()。私が.Count()どこでも使用することを強調した場合、コードはより再利用可能で保守しやすいでしょう。通常、より一般的なインターフェースを利用することを選択するのが最善の策です。より一般的な意味では、より多くの型によって実装されるより単純なインターフェースを意味し、したがってコード間の互換性が向上します。

私は.Count()あなたが書いているコードの再利用性をもっと扱う他の考慮事項があると言っているだけです。


2
+1ディスカッションへの貴重な追加。プロパティ.CountがHtmlAgilityPackのバージョンアップグレードに耐えられなかったため、私が維持している一部のコードが壊れました。
Dan Solovay 2014

1
それは両刃の剣かもしれません。いつか誰かがIEnumerableを真のジェネレーターになるように変更しようとするとどうなりますか。コードベースを見ると、.Count()が列挙可能なものを複数回
繰り返す

@bashrcTrue。開発者のコ​​ードの変更とフレームワークのコードの変更を検討している場合、開発者のコ​​ードが変更される可能性が高いと思います。そのような変更がフレームワークで行われた場合、それは多くのことを壊します。従来、これらの場合、開発者が必要に応じて移行できるように、新しいコレクション/インターフェイスが導入されていました。
AaronLS 2017年

20

この.Count()メソッド十分に賢いか、問題の型を知っている可能性があり、そうであれば、基になる.Countプロパティを使用する可能性があります。

それからまた、そうではないかもしれません。

コレクション.Count自体にプロパティがある場合、パフォーマンスに関してはそれが最善の策であると考えるのが安全だと思います。

.Count()メソッドがコレクションについて認識していない場合は、コレクションを列挙します。これはO(n)操作になります。


3
Countプロパティを使用する方が良い場合もありますが、使用するCount()メソッドの作成についてICollection<T>.Countは、msdn.microsoft.com
en

私はあなたがほとんどすべてを知っている方法を知りません。
snr

5

Count()methodは、の各要素を反復処理し、IEnumerable<>そこにある要素の数を返す拡張メソッドです。のインスタンスIEnumerableが実際にはである場合、すべての要素を繰り返すのではなくList<>Countプロパティを返すように最適化されています。


List <>がある場合でも、Count()メソッドを使用して、コードをより一般的にします。特定のコレクションを実装する必要がないIEnumerable <>を使用するようにクラスをリファクタリングする場合に適しています。
AntonioR 2011年

3

Count()LINQからの拡張メソッドとしてあります-s、実際の.NETコレクションオブジェクトのCountプロパティListです。

そのCount()ため、コレクション/クエリ可能なオブジェクトを列挙するため、ほとんどの場合、速度が低下します。リスト、キュー、スタックなどでは、を使用しますCount。または配列の場合- Length


3

ショートバージョン:CountプロパティとCount()メソッドのどちらかを選択できる場合は、常にプロパティを選択してください。

違いは主に操作の効率にあります。Countプロパティを公​​開するすべてのBCLコレクションは、O(1)方式で公開します。Count()ただし、この方法ではO(N)のコストがかかる可能性があり、多くの場合、コストがかかります。一部の実装では、O(1)に到達するためのチェックがいくつかありますが、それが保証されるわけではありません。


私はこの答えはカウントプロパティを使用する方が合理的だと思う
AT

3

CountorLengthプロパティがある場合は、Count()メソッドよりも常にそれを優先する必要があります。メソッドは通常、コレクション全体を反復処理して、その中の要素の数をカウントします。例外は、Count()メソッドがLINQ toSQLまたはLINQto Entitiesソースに対してである場合です。たとえば、その場合、データソースに対してカウントクエリを実行します。それでも、Count物件がある場合は、やるべきことが少ないので、それを好むでしょう。


3

このCount()メソッドは、任意ので機能するLINQメソッドですIEnumerable<>Count()メソッドがコレクション全体を反復処理してカウントを見つけることを期待しますが、LINQコードには、Countプロパティが存在するかどうかを検出し、存在する場合はそれを使用するための最適化が実際に含まれていると思います。

したがって、どちらもほぼ同じことを行う必要があります。そこに型チェックを行う必要がないため、Countプロパティはおそらくわずかに優れています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.