2012-01-01 10 views
5

IListとIEnumerableについて説明してくれてありがとうございます。私はそれにquestionとマークしました。今私はちょっとだけもっと情報を求めています。私はこのようなコードを持ってIListのメソッドまたはプロパティをカウントする

for (var index = 0; index < Model.Items.Count(); index++) 

をそれは、Countが()メソッドで、それが何回も実行されますよう、それは効率的ではないということ以前の記事で示唆されました。私は以下を試した:

for (var index = 0; index < Model.Items.Count; index++) 

これは動作するようです。

誰かが違いがあることを確認できますか?両方とも動作するので、私は100%確実ではありません。

以下が最も効率的でしょうか? foreachにIListまたはIEnumerableが必要ですか?

foreach(var item in Items) 
+0

を以前の質問 –

+0

へのリンクを入れてくださいprervious質問 – rene

答えて

4

Count()メソッド呼び出しは、実際には、静的Enumerable.Count()メソッドを呼び出します。これは、IListの実装でプロパティを使用するために最適化されていますが、これは動的な型チェックを必要とし、それでもプロパティを通過するため、プロパティを使用する方が効率的です。 .NET 3.5では、ICollection<T>のためにのみ最適化しますが、.NET 4では非汎用のICollectionも最適化します。詳細はmy Edulinq blog post on Countを参照してください。あなたの質問の最後のビットについては

foreachループがまたはより効率的であってもなくてもよいが、それはむしろ、より重要である私の見解でより読みやすいでしょう。あなたが本当に各エントリのインデックスを必要としない限り、私は間違いなくforeachを使用します。

+0

おかげでジョンを追加しました。 foreachにIListまたはIEnumerableが必要ですか? –

+0

@ Samantha2:厳密に言えば、どちらも実際には必要ありませんが、 'IEnumerable'(または' IEnumerable ')は' foreach'を使用できることを保証するのに十分です。 –

6

Count()拡張メソッドはIEnumerableをサポートするすべてのオブジェクトのために働く、とIEnumerable自体はアイテム数を報告する任意の手段を持っていないので、それは、それが本当のパフォーマンスヒットすることができIEnumerator、だ使用してIEnumerableインスタンスを反復処理するを有することができます何度も呼び出された場合。

あなたはCount()実装に見ればしかし、あなたはそれがICollectionタイプのために最適化された(IListを意味し、少なくともFW4.0におけるジェネリックと非ジェネリックの両方、およびIList<T>も最適化されている)ことがわかりますし、もしあなたのオブジェクトはICollectionCountプロパティの項目数を報告します)を実装すると、Count()メソッドはコレクションを繰り返し実行せずに項目数を返します。だからあなたはパフォーマンスの違いが見えません。それにもかかわらず、ICollectionまたはIListインスタンスがある場合は、直接Countプロパティを取得し、Count()メソッドの実装から独立しているのはなぜですか?

また、あなたが複数の呼び出し抑制する変数にCount()メソッドの戻り値をキャッシュできることを覚えておいてください:

var count = Model.Items.Count(); 
for(var index = 0; index < count; index++) { } 
関連する問題