string [] files = new string[2];
files[0] = "ThinkFarAhead.Example.Settings.Configuration_Local.xml";
files[1] = "ThinkFarAhead.Example.Settings.Configuration_Global.xml";
//Resharper complains this is an "access to modified closure"
for (int i = 0; i < files.Length; i++ )
{
// Resharper disable AccessToModifiedClosure
if(Array.Exists(Assembly.GetExecutingAssembly().GetManifestResourceNames(),
delegate(string name) { return name.Equals(files[i]); }))
return Assembly.GetExecutingAssembly().GetManifestResourceStream(files[i]);
// ReSharper restore AccessToModifiedClosure
}
Das Obige scheint gut zu funktionieren, obwohl ReSharper sich darüber beschwert, dass dies "Zugriff auf modifizierte Schließung" ist. Kann jemand Licht ins Dunkel bringen?
(Dieses Thema wurde hier fortgesetzt )
Antworten:
In diesem Fall ist es in Ordnung, da Sie den Delegaten tatsächlich innerhalb der Schleife ausführen .
Wenn Sie den Delegaten speichern und später verwenden, werden Sie jedoch feststellen, dass alle Delegaten beim Versuch, auf Dateien [i] zuzugreifen, Ausnahmen auslösen - sie erfassen die Variable
i
und nicht ihren Wert zum Zeitpunkt der Delegaten Schaffung.Kurz gesagt, es ist etwas, das Sie als potenzielle Falle beachten sollten , aber in diesem Fall tut es Ihnen nicht weh.
Am Ende dieser Seite finden Sie ein komplexeres Beispiel, bei dem die Ergebnisse nicht intuitiv sind.
quelle
Ich weiß, dass dies eine alte Frage ist, aber ich habe kürzlich Verschlüsse untersucht und dachte, ein Codebeispiel könnte nützlich sein. Hinter den Kulissen generiert der Compiler eine Klasse, die einen lexikalischen Abschluss für Ihren Funktionsaufruf darstellt. Es sieht wahrscheinlich so aus:
Wie oben erwähnt, funktioniert Ihre Funktion, da die Prädikate unmittelbar nach der Erstellung aufgerufen werden. Der Compiler generiert Folgendes:
Wenn Sie andererseits die Prädikate speichern und später aufrufen würden, würden Sie sehen, dass jeder einzelne Aufruf der Prädikate tatsächlich dieselbe Methode für dieselbe Instanz der Abschlussklasse aufruft und daher denselben Wert für verwendet ich.
quelle
"files" ist eine erfasste äußere Variable, da sie von der anonymen Delegatenfunktion erfasst wurde. Die Lebensdauer wird durch die anonyme Delegatenfunktion verlängert.
Äußere Variablen auf MSDN
quelle