Betrachten Sie den folgenden Code, der eine Liste von Delegaten initialisiert, von denen jeder eine Methode SayGreetingToType mit einem bestimmten Typ und einer bestimmten Begrüßung aufruft:
<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>
Beim Ausführen dieses Codes würden Sie Folgendes erwarten:
Hi String Hi Single Hi Int32
Aufgrund des Abschlussverhaltens wird jedoch der letzte Typ im Typenarray, Int32, von allen Lambda erfasst Ausdrücke. Infolgedessen rufen alle Delegaten SayGreetingToType mit demselben Typ auf, was zur unerwarteten Ausgabe von Folgendem führt:
Hi Int32 Hi Int32 Hi Int32
Die Lösung
Um dieses Problem zu lösen, müssen wir um den Wert der Schleifenvariablen innerhalb des Lambda-Ausdrucks anstelle der Variablen selbst zu erfassen:
<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>
Diese Änderung stellt sicher, dass jeder Lambda-Ausdruck eine eigene Kopie des Typs hat, sodass er SayGreetingToType mit dem richtigen Aufruf aufrufen kann Typargument.
Das obige ist der detaillierte Inhalt vonWarum erfasst ein Lambda-Ausdruck innerhalb einer Foreach-Schleife den letzten Wert der Schleifenvariablen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!