Foreach Variable in Closure. Warum unterscheiden sich die Ergebnisse für diese Snippets? [Duplikat]

8

Kann jemand erklären, warum dieser Ausschnitt:

%Vor%

Funktioniert anders als dieses:

%Vor%

Im ersten Snippet beginnen alle Aufgaben mit ihrer eigenen Nachricht, während im zweiten Snippet alle Aufgaben mit der gleichen Nachricht beginnen?

Resharper gibt diese Beschreibung: "Zugriff auf foreach-Variable in Closure. Kann ein anderes Verhalten haben, wenn es mit verschiedenen Versionen des Compilers kompiliert wird." Warum kann es ein anderes Verhalten haben?

    
Ivan P. 05.04.2013, 15:05
quelle

2 Antworten

16
  

Resharper gibt diese Beschreibung: "Zugriff auf foreach-Variable in Closure. Kann ein anderes Verhalten haben, wenn es mit verschiedenen Versionen des Compilers kompiliert wird." Warum kann es ein anderes Verhalten haben?

Es gab eine bahnbrechende Änderung zwischen C # 4 und C # 5 aufgrund der Art und Weise, wie die Schleifenvariable in foreach durch Closures beeinflusst wurde, insbesondere seit der Einführung von Lambda-Ausdrücken in C # 3. Resharper warnt Sie davor abhängen oder auf andere Weise die frühere Semantik erwarten.

Das schnelle Ergebnis ist, dass in C # 4 die Schleifenvariable zwischen jeder Iteration der Schleife geteilt wurde und dass Closures die Variable erfassen. Dies führte zu unerwarteten Ergebnissen für die meisten Menschen, wenn sie die Schleifenvariable schlossen.

In C # 5 erhält jede Iteration der Schleife ihre eigene Variable, sodass die Closures in einer Iteration nicht über die gleiche Variable wie andere Iterationen geschlossen werden, was zu mehr erwarteten Ergebnissen führt (für die meisten Menschen).

Das bringt uns zum Kern Ihres Problems:

  

Im ersten Snippet beginnen alle Aufgaben mit ihrer eigenen Nachricht, während im zweiten Snippet alle Aufgaben mit der gleichen Nachricht beginnen?

In Ihrem ersten Snippet erstellen Sie eine Kopie der Loop-Variablen innerhalb Ihrer Schleife, und die Schließung erfolgt über die innere Variable. In der zweiten schließen Sie direkt über die Schleifenvariable. Vermutlich laufen Sie unter C # 4, also gilt die frühere Semantik. Wenn in C # 5 ausgeführt wird, sollten die Schleifenausgaben beider Versionen konsistent sein. Dies ist die Änderung, auf die sich Resharper bezieht, und Sie sollten auch verstehen, wie Sie Ihren Code in C # 4 strukturieren (verwenden Sie also die erste Version, die Sie geschrieben haben).

Wie Justin Pihony in den Kommentaren hervorhebt, hat Eric Lippert ein sehr nützlicher Blog-Artikel zu der früheren Semantik spielt auch auf die Änderung für C # 5 an.

    
Anthony Pegram 05.04.2013, 15:07
quelle
2

Ihr zweites Codebeispiel hat eine einzelne messageToSend , die alle Lambda-Ausdrücke in ihren Closures erfassen.

Wenn die Delegierten ausgeführt werden, verwenden sie den aktuellen Wert der Variablen.

    
SLaks 05.04.2013 15:07
quelle

Tags und Links