Ich speichere eine Aktion in einer lokalen Variablen, dann benutze ich danach, dass die lokale Variable außerhalb des Bereichs liegt. Besteht die Gefahr, dass ich gereinigt werde, bevor ich es benutze? Hier ist ein Beispiel:
%Vor% Sie können also in diesem Beispiel sehen, dass die Funktion eine Liste von Aktionen zurückgibt, die baseMap
aufrufen. baseMap
ist nur eine lokale Variable. Ist die Tatsache, dass es innerhalb der anderen Aktionen aufgerufen wird genug für .NET, um es nicht zu bereinigen?
Ich beziehe mich auf Abschnitt 5.1.7 der C # 4-Spezifikation, die besagt:
Wenn die lokale Variable von einer anonymen Funktion erfasst wird, erstreckt sich ihre Lebensdauer mindestens so lange, bis die von der anonymen Funktion erstellte Delegat- oder Ausdrucksstruktur zusammen mit anderen Objekten, die die aufgezeichnete Variable referenzieren, für die Garbage Collection geeignet ist.
Auch wenn die Kontrolle das Ende des Bereichs des lokalen Bereichs überschreitet, wird die Lebensdauer des lokalen Bereichs erweitert. In der Praxis machen wir das, indem wir das local in ein Feld einer closure-Klasse verwandeln und dann die Klasse am Leben erhalten, indem wir sie im Delegate (oder im Ausdrucksbaum) referenzieren.
Beachten Sie jedoch, dass Sie auf das gegenteilige Problem stoßen können; Manchmal leben die Dinge länger als du willst:
%Vor%Wie dies heute in C # funktioniert, ist die Schließung, die für die zwei Delegierten generiert wird, die sowohl "billig" als auch "teuer" am Leben erhält, solange der Delegierte mit längerer Lebensdauer nicht wirklich lebt Verwenden Sie "teuer"! (VB, JScript und viele andere Sprachen, die Schließungen haben, haben dieses Problem ebenfalls.)
Was wir hier tun könnten, ist, diese Situation im Compiler zu erkennen und zwei Closures zu erzeugen. Wir überlegen, dies für eine zukünftige Version von C # zu tun.
Nein, es ist nicht in Gefahr. Eine anonyme Methode, die eine lokale Variable außerhalb dieser anonymen Methode verwendet, wird in eine neue Klasse mit einem Feld kompiliert, das diese lokale Variable und eine Methode speichert, die der anonymen Methode entspricht.
In Ihrem Fall wird dies etwa wie folgt aussehen:
%Vor%Die Initialisierung der Liste sieht dann ungefähr so aus:
%Vor%BTW: Ihre Syntax ist ein bisschen aus. Die Listenerstellung wird nicht kompiliert. Es sollte so aussehen:
%Vor%Tags und Links c# .net-4.0 memory-management