2011-06-23 7 views
7
List<string> list = new List<string>() {"a", "b", "c"}; 
IEnumerable<string> enumerable = list; 

int c1 = list.Count; 
int c2 = list.Count(); 
int c3 = enumerable.Count(); 

これらの最後の3つのステートメントの間にパフォーマンスと実装に違いはありますか? list.Count()list.Countと悪化しますか?参照のタイプがIEnumerable<string>の場合は重要ですか?Count()(linq拡張子)とListの間に違いがありますか?

答えて

10

のは、リフレクターで見てみましょう:あなたのIEnumerable<T>ICollection<T>ICollectionを実装している場合

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

そう、それはCountプロパティを返します。

0

私はそれがこのように動作すると仮定します。リストは、変数に自身のカウントを保持します。 Count()はIEnumerableをループし、要素の数を数えます。それはList.Countをより効率的にするでしょう。

+0

IEnumerableがListなどのICollectionであり、したがって.Countプロパティを持つ場合、Linqは.Count()メソッドを使用するときにこれをショートカットとして使用します。つまり、どちらを使用しても問題はありません。 – Dolbz

+0

これは間違っています。 Count()は、Count()を呼び出している要素がICollection自体を実装していない場合にカウントするためにのみループするようにコーディングされています。 –

3

Linq Countメソッドは、ICollectionインターフェイスを実装しているため、既にCountプロパティを持っている場合は、基になるコレクションを反復処理しないほど巧妙です。

1

IEnumerableでのカウントの実装では、最初に、列挙可能リストがICollection<T>を実装しているかどうかをチェックします。ここで、Tは列挙可能リストの汎用パラメータです。

もしそうなら、ICollection<T>.Countを返します。

そうでない場合は、ICollectionを実装しているかどうかを確認します。そうであればICollection.Countを返します。

リストとカウントを繰り返す必要がないものが実装されていない場合は、大きなリストでは高価な操作になる可能性があります。

List<string>しかし、ICollection<string>を実装しているため、パフォーマンスは同じになります。

関連する問題