2012-04-13 2 views
2

Ich habe versucht, das Verhalten von Erweiterungsmethoden von C# und fand unten, was zu verstehen:Verwirrende Verhalten von Erweiterungsmethode mit neuer Objekterstellung in Methode

Im Folgenden finden Sie Erweiterungsmethode auf Klasse-Programm, das SeeIT genannt ein Feld hat.

public static void Prod(this Program p) 
{ 
    Console.WriteLine("i am in ext- pro"); 
    p = new Program(); // look out for this line (call this line as #@2) 
    p.SeeIt = 100; 
} 

Nun, wenn ich rufe diese Methode wie folgt aus:

var pr = new Program(); 
pr.SeeIt = 200; 

pr.Prod(); 

COnsole.WriteLine(pr.SeeIt); 

ich unten Dinge sehen:

  1. Wenn ich # @ 2 Zeile in Erweiterungsmethode kommentieren, ist das Ergebnis von Erweiterungsmethode dh 100.
  2. Wenn ich Linie # @ 2 Zeile, Ergebnis ist 200.

Ich möchte wissen:

  • Was genau mit i p = new Program() in Verlängerung Methode sagen, es geschieht?
+0

Haben Sie versucht, den Debugger-Fluss vor dem Posten dieser Frage – joshua

+0

Es gibt nicht viel im Code zu debuggen. – Rupal

+2

Dann nehme ich an, Sie wissen nicht über die Nachricht – joshua

Antwort

5

Grundsätzlich verhält es sich genau das gleiche wie ohne die this. Erweiterungsmethoden machen die API nur praktisch - sie ändern das Verhalten nicht.

Der Parameter p nicht ref weitergegeben, so sobald Sie p = new Program(); tun haben Sie eine separate und unabhängige Instanz geschaffen, die den anrufenden Code nicht zur Verfügung zurück. Folglich wird der Anrufer Ihre Änderung nicht sehen und die 100 wird nur in Prod sichtbar sein.

Oder genauer gesagt:

pr.Prod(); 

ist identisch mit

DeclaringType.Prod(pr); 

, die den Wert von pr (die Referenz) auf den Stapel geladen, und fordert über statische Prod-Anruf;

public static void Prod(this Program p) 

an diesem Punkt p auf dem Stapel in Position arg0.

p = new Program(); 

ein neues Objekt erstellt und weist den Wert überarg0 - beachten Sie, dass Wert von pr (die Referenz) wird hierdurch nicht beeinflusst, wie arg0 eine separate Speicherstelle für die Referenz.

p.SeeIt = 100; 

weist ein Element zum Objekt neuen Objekt durch arg0 dereferencing - wieder das Objekt am Endepr weiß nichts darüber.

+0

übergeben :) danke. das macht es klar. – Rupal

0

Es erstellt eine neue Instanz von Program und Sie aktualisieren die SeeIt Eigenschaft dieser Instanz.

a) Wenn # @ 2 kommentieren Sie den Wert der ursprünglichen Instanz des Programms aktualisieren und damit die Eigenschaft 100 gesetzt

b) Wenn Sie eine neue Instanz die alte Instanz erstellen ist nicht betroffen und die Eigenschaftswert ist nicht betroffen

0

Sie ersetzen die Referenz von p durch eine andere Instanz, die sich nicht auf die Referenz auswirkt, die Sie an die Erweiterungsmethode übergeben haben. Ich glaube, Sie haben versucht, Parameter p zu einem ref-Parameter zu machen. In diesem Fall wären die Referenzen zwischen dem, was an die Methode übergeben wurde und in der Methode selbst verwendet wird, gleich.

Leider können Sie keine Erweiterungsmethoden verwenden, die diesen Parameter referenzieren.

Denken Sie daran, eine Referenz ist im Grunde ein Zeiger auf eine tatsächliche Klasse Instanz.