新しいResharperバージョン6を使用しています。コード内のいくつかの場所で、テキストに下線が引かれ、IEnumerableの複数の列挙が可能の可能性があることを警告しています。
私はこれが何を意味するのかを理解しており、適切な場合にはアドバイスをとってきましたが、場合によっては、それが実際に大したことであるかどうかわかりません。
次のコードのように:
_var properties = Context.ObjectStateManager.GetObjectStateEntry(this).GetModifiedProperties();
if (properties.Contains("Property1") || properties.Contains("Property2") || properties.Contains("Property3")) {
...
}
_
2行目のproperties
の言及に下線を引いて、このIEnumerableを複数回列挙していることを警告しています。
行1の終わりに.ToList()
を追加すると(properties
が_IEnumerable<string>
_から_List<string>
_に変わります)、警告が消えます。
しかし、確かに、それをリストに変換すると、最初にIEnumerable全体を列挙してリストを作成し、必要に応じてリストを列挙してプロパティを検索します(つまり、1つの完全列挙と3つの部分列挙) )。私の元のコードでは、3つの部分的な列挙のみを行っています。
私が間違っている?ここで最良の方法は何ですか?
properties
が実際に何であるかは正確にはわかりませんが、本質的に非具体化データベースクエリを表す場合、if
ステートメントは3つのクエリを実行します。
私容疑者するほうが良いでしょう:
string[] propertiesToFind = { "Property1", "Property2", "Property3" };
if (properties.Any(x => propertiesToFind.Contains(x))
{
...
}
論理的にシーケンスを1回だけ繰り返す-データベースクエリが含まれている場合は、SQLの "IN"句を使用して、データベース内のすべてのクエリを1つのクエリで実行できる可能性があります。 。
IEnumerableでContains()
を呼び出すと、拡張メソッドが呼び出され、アイテムを見つけるためにアイテムを反復処理します。 IList
にはContains()
の実際の実装があり、これは通常の値の反復よりも効率的です(ハッシュを使用した検索ツリーがある可能性があります)。したがって、IList
で警告されません。
拡張メソッドはそれがIEnumerable
であることを認識するだけなので、理論的には既知の型を識別してそれに応じてキャストすることは可能ですが、Contains()
の組み込みメソッドを利用することはできませんそれらを活用してください。