Erfasste Variablen in Lambda-Ausdrücken: Das Geheimnis der „foreach-Schleifenvariablen“ entmystifizieren
Betrachten Sie den folgenden verwirrenden Code, der darauf abzielt, eine Liste zu erstellen von Methoden, die verschiedene Datentypen begrüßen:
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) { var sayHello = new PrintHelloType(greeting => SayGreetingToType(type, greeting)); helloMethods.Add(sayHello); } foreach (var helloMethod in helloMethods) { Console.WriteLine(helloMethod("Hi")); } } public string SayGreetingToType(Type type, string greetingText) { return greetingText + " " + type.Name; } }
Wenn Sie diesen Code jedoch ausführen, stoßen Sie auf ein unerwartetes Ergebnis: Er gibt dreimal „Hi Int32“ aus, anstelle des beabsichtigten „Hi String“, „Hi Single“, „Hi Int32“. Was ist hier los?
Die Subtilität von Abschlüssen und erfassten Variablen
Der Schlüssel zum Verständnis dieses Verhaltens liegt im Konzept von Abschlüssen und erfassten Variablen. Wenn ein Lambda-Ausdruck erstellt wird, erfasst er die Variablen aus seinem umgebenden Bereich. In diesem Fall erfasst der Lambda-Ausdruck die Typvariable aus der foreach-Schleife.
Erfasste Schleifenvariablen: Eine Gefahr
Entscheidend ist, dass die erfasste Variable nicht der Wert von ist Typ, sondern die Variable selbst. Während die Schleife fortschreitet, ändert sich die Typvariable, während die Lambda-Ausdrücke immer noch auf dieselbe erfasste Variable verweisen.
Problem beheben
Um das beabsichtigte Verhalten zu erreichen, ist es Es ist notwendig, eine neue Variable innerhalb der Schleife zu erstellen, um den beabsichtigten Wert zu erfassen. So ändern Sie den Code:
foreach (var type in types) { var newType = type; var sayHello = new PrintHelloType(greeting => SayGreetingToType(newType, greeting)); helloMethods.Add(sayHello); }
Durch die Erfassung von newType anstelle des Typs haben die Lambda-Ausdrücke jetzt einen konstanten Verweis auf den beabsichtigten Wert und die erwartete Ausgabe wird erhalten.
Fazit
Bei der Arbeit mit Lambda-Ausdrücken ist es wichtig, die Feinheiten von Abschlüssen und erfassten Variablen zu verstehen. Indem Sie diese Mechanismen berücksichtigen, können Sie unerwartetes Verhalten vermeiden und sicherstellen, dass Ihr Code wie vorgesehen funktioniert.
Das obige ist der detaillierte Inhalt vonWarum erfassen alle Lambda-Ausdrücke in einer foreach-Schleife dieselbe Variable und nicht ihre einzelnen Werte?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!