C # delegiert, Referenzauflösungszeit

7

Ich habe eine einfache Frage zu .net-Delegierten. Sprich ich habe so etwas:

%Vor%

Die erste Funktion umschließt einen Verweis auf this.Value . Wenn während der Laufzeit die erste Methode mit generischem Parameter aufgerufen wird, liefert sie this.Value irgendwie an die zweite, aber wie? Diese kamen mir in den Sinn:

  • Aufruf nach Wert (struct) - Der aktuelle Wert von this.Value wird übergeben. Wenn der m_TaskQueue 5 Minuten später ausgeführt wird, ist der Wert nicht in seinem letzten Status Es war beim ersten Referenzieren.
  • Aufruf über Referenz (Referenztyp) - dann wird der letzte Status von Value während der Ausführung der Aktion referenziert, aber wenn ich this.Value vor der Ausführung der Aktion zu einer anderen Referenz ändere, wird es weiterhin sein auf die alte Referenz zeigen
  • Nach Namen anrufen (beide) - wobei this.Value ausgewertet wird, wenn die Aktion aufgerufen wird. Ich glaube, die tatsächliche Implementierung würde einen Verweis auf this enthalten und dann Value darauf während der tatsächlichen Ausführung des Delegaten auswerten, da kein Anruf über den Namen erfolgt.

Ich nehme an, es wäre Call of Name Style, aber ich konnte keine Dokumentation finden, also frage ich mich, ob es ein wohldefiniertes Verhalten ist. Diese Klasse ist so etwas wie ein Schauspieler in Scala oder Erlang, also brauche ich es threadsicher. Ich möchte nicht, dass Invoke function Value sofort dereferenziert, das wird in einem sicheren Thread für this object von m_TaskQueue gemacht.

    
Ekin Koc 16.02.2010, 22:42
quelle

3 Antworten

18

Lassen Sie mich Ihre Frage beantworten, indem Sie beschreiben, welchen Code wir tatsächlich dafür generieren. Ich werde Ihre andere Invoke-Methode mit verwirrenden Namen umbenennen. Es ist nicht notwendig zu verstehen, was hier vor sich geht.

Angenommen, Sie sagten

%Vor%

Der Compiler generiert Code, als ob Sie tatsächlich geschrieben hätten:

%Vor%

Beantwortet das Ihre Frage?

    
Eric Lippert 16.02.2010, 23:00
quelle
7

Der Delegat speichert einen Verweis auf die Variable, nicht den Wert davon. Wenn Sie den aktuellen Wert beibehalten möchten (vorausgesetzt, es handelt sich um einen Werttyp), müssen Sie eine lokale Kopie davon erstellen:

%Vor%

Wenn es sich um einen veränderbaren Referenztyp handelt, können Sie eine lokale Kopie / tiefe Kopie erstellen.

    
Mark Byers 16.02.2010 22:44
quelle
3

Der wahre Schlüssel ist, sich daran zu erinnern, dass der Bereich lexikalisch ist; Es ist etwas, auf das der Compiler aufpasst. Es erfasst also Variablen , nicht ihre Werte . Ob diese Werte Werttypen oder Referenztypen sind, ist eine andere Sache.

Vielleicht hilft ein etwas extremeres Beispiel, das Verhalten des Delegaten zu ändern:

%Vor%

druckt "etwas ganz anderes". In diesem Licht spielt es keine Rolle, wie oft Sie die Funktion umbrechen, speichern oder verschieben. Es bezieht sich immer noch auf die Variable, die es beigefügt hat. Kurz gesagt, was zählt, ist der Wert der eingeschlossenen Variablen, wenn der Delegierte tatsächlich ausgeführt wird.

    
user24359 16.02.2010 23:03
quelle