デリゲートのリストを初期化する次のコードを考えます。各デリゲートは、特定の種類と挨拶を指定してメソッド SayGreetingToType を呼び出します。
<code class="csharp">public class MyClass { public delegate string PrintHelloType(string greeting); public void Execute() { Type[] types = new Type[] { typeof(string), typeof(float), typeof(int) }; List<PrintHelloType> helloMethods = new List<PrintHelloType>(); foreach (var type in types) { // Initialize the lambda expression with the captured variable 'type' var sayHello = new PrintHelloType(greeting => SayGreetingToType(type, greeting)); helloMethods.Add(sayHello); } // Call the delegates with the greeting "Hi" foreach (var helloMethod in helloMethods) { Console.WriteLine(helloMethod("Hi")); } } public string SayGreetingToType(Type type, string greetingText) { return greetingText + " " + type.Name; } }</code>
このコードを実行すると、次の結果が表示されると予想されます。
Hi String Hi Single Hi Int32
ただし、クロージャーの動作により、types 配列の最後の型 Int32 はすべてのラムダによってキャプチャされます。表現。その結果、すべてのデリゲートが同じ型で SayGreetingToType を呼び出し、次のような予期しない出力が発生します。
Hi Int32 Hi Int32 Hi Int32
解決策
この問題を解決するには、次のことが必要です。変数自体ではなくラムダ式内のループ変数の値をキャプチャするには:
<code class="csharp">public class MyClass { public delegate string PrintHelloType(string greeting); public void Execute() { Type[] types = new Type[] { typeof(string), typeof(float), typeof(int) }; List<PrintHelloType> helloMethods = new List<PrintHelloType>(); foreach (var type in types) { // Capture a copy of the current 'type' value using a new variable var newType = type; // Initialize the lambda expression with the new variable 'newType' var sayHello = new PrintHelloType(greeting => SayGreetingToType(newType, greeting)); helloMethods.Add(sayHello); } // Call the delegates with the greeting "Hi" foreach (var helloMethod in helloMethods) { Console.WriteLine(helloMethod("Hi")); } } public string SayGreetingToType(Type type, string greetingText) { return greetingText + " " + type.Name; } }</code>
この変更により、各ラムダ式が型の独自のコピーを持つことが保証され、正しい値で SayGreetingToType を呼び出すことができるようになります。型引数。
以上がForeach ループ内のラムダ式がループ変数の最後の値をキャプチャするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。