簡単なコードを書いていて、このコンパイラエラーに気づきました
ラムダ式で反復変数を使用すると、予期しない結果が生じる場合があります。
代わりに、ループ内にローカル変数を作成し、反復変数の値を割り当てます。
私はそれが何を意味するかを知っており、大したことではなく、簡単に修正できます。
しかし、ラムダで反復変数を使用するのがなぜ悪い考えなのか疑問に思っていましたか?
後でどのような問題を引き起こす可能性がありますか?
次のコードを検討してください。
List<Action> actions = new List<Action>();
for (int i = 0; i < 10; i++)
{
actions.Add(() => Console.WriteLine(i));
}
foreach (Action action in actions)
{
action();
}
これは何を印刷すると思いますか?明らかな答えは 0...9 ですが、実際には 10 回、10 回印刷されます。これは、すべてのデリゲートによってキャプチャされる変数が 1 つしかないためです。これは予想外のこの種の動作です。
編集: C# ではなく VB.NET について話していることがわかりました。VB.NET には、変数が反復間で値を維持する方法があるため、さらに複雑なルールがあると思います。Jared Parsons によるこの投稿では、関連する問題の種類についていくつかの情報が提供されていますが、2007 年から戻っているため、実際の動作はそれ以降変更されている可能性があります。
ここでC#を意味すると仮定します。
これは、コンパイラがクロージャを実装する方法が原因です。反復変数を使用すると、変更されたクロージャーにアクセスする際に問題が発生する可能性があります (メソッド内の他の内容によっては発生しない場合があり、実際に問題が発生する場合があるため、問題が発生するのは「できない」と述べたことに注意してください)。変更されたクロージャにアクセスします)。
より詳しい情報:
http://blogs.msdn.com/abhinaba/archive/2005/10/18/482180.aspx
さらに詳しい情報:
http://blogs.msdn.com/oldnewthing/archive/2006/08/02/686456.aspx
http://blogs.msdn.com/oldnewthing/archive/2006/08/03/687529.aspx
http://blogs.msdn.com/oldnewthing/archive/2006/08/04/688527.aspx