Lambda-Ausdrücke und Schleifeniterationsvariablen: Eine potenzielle Gefahr
Von der direkten Verwendung von Schleifeniterationsvariablen innerhalb von Lambda-Ausdrücken wird generell abgeraten. Diese Vorgehensweise kann aufgrund der Art und Weise, wie Lambda-Ausdrücke mit der Variablenerfassung umgehen, zu unerwarteten Ergebnissen führen.
Lambda-Ausdrücke erfassen den Referenz auf eine Variable, nicht ihren Wert zum Zeitpunkt der Erfassung. Wenn eine Schleife iteriert, verweisen daher alle innerhalb der Schleife erstellten Lambda-Ausdrücke auf dieselbe, sich ständig ändernde Iterationsvariable. Dies führt dazu, dass alle Lambdas letztendlich den endgültigen Wert der Variablen nach Abschluss der Schleife verwenden, nicht ihren Wert zum Zeitpunkt der Erstellung jedes Lambdas.
Lassen Sie uns dies anhand eines VB.NET-Beispiels veranschaulichen:
<code class="language-vb.net">Dim actions = new List(Of Action)() For i As Integer = 0 To 9 actions.Add(New Action(Function() Console.WriteLine(i))) Next For Each action As Action In actions action() End For</code>
Man könnte erwarten, dass dies 0 bis 9 ausgibt. Stattdessen wird 10 zehnmal gedruckt! Dies liegt daran, dass jedes Action
in der actions
-Liste auf dasselbe i
verweist und zum Zeitpunkt der Ausführung der zweiten Schleife i
bereits seinen Endwert von 10 erreicht hat.
Das Problem wird verstärkt, wenn der Schleifenkörper Nebenwirkungen hat, die sich auf die Variable auswirken, auf die der Lambda-Ausdruck verweist. Dies kann zu schwer zu debuggenden Inkonsistenzen führen.
Die Lösung: Erstellen Sie eine lokale Kopie
Um dies zu verhindern, erstellen Sie eine lokale Kopie der Iterationsvariablen innerhalb der Schleife:
<code class="language-vb.net">Dim actions = new List(Of Action)() For i As Integer = 0 To 9 Dim localI As Integer = i ' Create a local copy actions.Add(New Action(Function() Console.WriteLine(localI))) Next For Each action As Action In actions action() End For</code>
Jetzt erfasst jeder Lambda-Ausdruck eine eindeutige localI
Variable, die ihren Wert zum Zeitpunkt der Erstellung behält. Die Ausgabe wird korrekterweise 0 bis 9 sein. Diese einfache Änderung stellt sicher, dass jedes Lambda mit seinem eigenen unabhängigen Wert arbeitet, wodurch unerwartetes Verhalten vermieden wird.
Das obige ist der detaillierte Inhalt vonWarum führen Lambda-Ausdrücke in Schleifen zu unerwarteten Ergebnissen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!