Ist dies ein Beispiel für eine Schließung in C #?

8
%Vor%

Ich verstehe, dass x nicht wirklich als Variable deklariert ist, zB. var x = 3. Stattdessen wird es in die äußere Funktion übergeben, die eine Funktion zurückgibt, die den ursprünglichen Wert zurückgibt. Zu der Zeit, zu der es dies zurückgibt, erzeugt es eine Schließung um x, um sich an seinen Wert zu erinnern. Später, wenn Sie s ändern, hat das keine Auswirkung.

Stimmt das?

(Ausgabe ist übrigens 3, was ich erwarten würde).

Edit: Hier ist ein Diagramm, warum ich denke, dass es

ist

x = 3 wird in das func übergeben und gibt eine Funktion zurück, die einfach x zurückgibt. Aber x existiert nicht in der inneren Funktion, nur sein Elternteil, und sein Elternteil existiert nicht mehr, nachdem ich es null gemacht habe. Wo wird x gespeichert, wenn die innere Funktion ausgeführt wird? Es muss eine Schließung vom übergeordneten erstellen.

Weitere Klarstellung:

%Vor%

Ausgabe ist 0, 1, 2, 3, 4

Aber mit Ihrem Beispiel:

%Vor%

Die Ausgabe ist 5 5 5 5 5, was nicht das ist, was Sie wollen. Es hat den Wert der Variablen nicht erfasst, es wurde lediglich ein Verweis auf das Original s beibehalten.

Closures werden in Javascript genau erstellt, um dieses Problem zu vermeiden.

    
NibblyPig 12.06.2012, 14:39
quelle

2 Antworten

12

Nein, das ist kein Abschluss für s , x ist nur ein Argument für den Lambda-Ausdruck, der einen Delegaten erzeugt (der eigentlich zu x => () => x vereinfacht werden könnte.

) %Vor%

Sie erhalten 3 und 5 wie erwartet. In keinem Fall erinnert es sich tatsächlich an x von der anderen Zeit, aber schließt während der Dauer des äußeren Lambda lokal auf x .

Grundsätzlich erstellt jeder Aufruf von x => () => x einen neuen () => x -Delegaten, der den lokalen Wert von x (nicht von s , der übergeben wurde) erfasst.

Auch wenn Sie s verwenden und es übergeben und ändern, erhalten Sie immer noch 3 und 5 :

%Vor%

Nun erfasst die lokale Variable x innerhalb der lokalen Funktion, die bei jedem Aufruf generiert wird. Daher wird% code_% zwischen den Aufrufen des größeren Lambda nicht bestehen bleiben, aber es wird erfasst, wenn es später im Lambda geändert wird.

Nehmen wir zum Beispiel an, Sie hätten Folgendes:

%Vor%

In diesem Fall ist die Schließung von x innerhalb der anonymen Methode offensichtlicher. Die Ergebnisse dieser Ausführung sind 30 und 50, da Änderungen an x innerhalb der anonymen Methode die Schließung von x local für diese anonyme Methode beeinflussen, diese jedoch nicht zwischen den Aufrufen übertragen werden, da nur das lokale erfasst wird x wurde an die anonyme Methode übergeben und nicht an die x , um sie aufzurufen.

Also, um es zusammenzufassen, in Ihrem Diagramm und Beispiel: * main übergibt s an das größere Lambda ( func in Ihrem Diagramm) * func schließt sich zum Zeitpunkt des Aufrufs von s , um die anonyme Methode x

zu generieren

Sobald der Aufruf zum äußeren Lambda gemacht wurde (func), beginnt und endet der nähere, weil er nur lokal zu diesem Lambda ist und nicht auf irgendetwas von main schließt.

Hilft das?

    
James Michael Hare 12.06.2012, 14:41
quelle
4

Nein, ändern Sie

%Vor%

bis

%Vor%

und es schließt über die Variable s .

    
Jesse C. Slicer 12.06.2012 14:44
quelle

Tags und Links