3

これがサンプルコードです。

var values = new List<string>() { "Stack", "Over", "Go" };

var funcs = new List<Func<string>>();

foreach(var v in values) 

  funcs.Add( ()=>v );
foreach(var f in funcs) 

  Console.WriteLine(f());

Visual Studio 2010でこのコードを実行すると、次のような出力が得られました。 Go Go Go

しかし、Visual Studio 2012で同じコードを試したところ、出力は次のようになりました。 Stack Over Go

なぜ動作が異なるのですか?

4

1 に答える 1

10

その理由は、クロージャにキャプチャされた変数の一時コピーを作成するようにコンパイラが変更されたためです。

VS2012では次のコードを使用します。

foreach(var v in values) 
    funcs.Add(() => v);

VS 2012コンパイラがこれから生成するコードは、このコードに対してVS2010コンパイラによって生成されるコードと同等です。

foreach(var v in values) 
{
    var tmp = v;
    funcs.Add(() => tmp);
}

この変更の理由は、多くの開発者がVS2010コンパイラの動作が予期しないものであると感じたという事実でした。

于 2013-02-25T11:33:56.387 に答える