C#でラムダ式または無名メソッドを使用する場合、変更されたクロージャーの落とし穴へのアクセスに注意する必要があります。例えば:
foreach (var s in strings)
{
query = query.Where(i => i.Prop == s); // access to modified closure
...
}
変更されたクロージャのため、上記のコードではWhere
、クエリのすべての句がの最終値に基づいていますs
。
ここで説明したように、これs
は、foreach
上記のループで宣言された変数がコンパイラで次のように変換されるために発生します。
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
このようにする代わりに:
while (enumerator.MoveNext())
{
string s;
s = enumerator.Current;
...
}
ここで指摘したように、ループの外側で変数を宣言してもパフォーマンス上の利点はありません。通常の状況では、これを行うために考えられる唯一の理由は、ループのスコープ外で変数を使用する場合です。
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
var finalString = s;
ただし、foreach
ループで定義された変数はループの外では使用できません。
foreach(string s in strings)
{
}
var finalString = s; // won't work: you're outside the scope.
そのため、コンパイラーは変数を宣言しますが、多くの場合、発見やデバッグが難しいエラーが発生しやすく、認識できる利点はありません。
foreach
この方法でループを使用してループを実行できる場合、それらが内部スコープ変数を使用してコンパイルされた場合は不可能でしたか、それとも、匿名メソッドとラムダ式が利用可能または一般的になる前に行われた任意の選択であり、それ以来改訂されていませんか?
foreach
いませんが、ラムダ式について話しているため、OPで示されているのと同様のコードが生成されます...
String s; foreach (s in strings) { ... }
ますか?