2010-11-18 6 views
2

Kann jemand das Verhalten des folgenden Codes erklären. Die Ausgabe des folgenden Codes ist die Zeichenfolge "str" ​​und der Wert von i ist 100.Objekt Verhalten

Aber warum ist es so? Nachdem das Objekt c1 = null gesetzt wurde, warum ist es nicht null?

public class Class1 
{ 
    public int i; 
    public Class1() 
    { 
     i = 10; 
    }  

    public string method1() 
    { 
     return "str"; 
    } 
} 

public class Class2 
{ 
    public void method2(Class1 c1) 
    { 
     c1.i = 100; 
     c1 = null; 
    } 
} 

    void main() 
    { 
     Class1 c1 = new Class1(); 
     Class2 c2 = new Class2(); 
     c2.method2(c1); 
     Response.Write(c1.method1()); 
     Response.Write(c1.i.ToString()); 
    } 

Antwort

3

Dies ist eine Pass-by-Referenz/Pass-by-Value-Sache. Javaranch Camp site stories: Pass By Value Please erklärt es sehr gut. Ich weiß, dass der obige Link für Java ist, und dies ist eine C# -Frage, aber das gleiche passiert (wenn das Schlüsselwort "ref" nicht verwendet wird).

+0

Und hier ist ein guter C# -spezifischen Artikel: http://www.yoda.arachsys.com/csharp/parameters.html – LukeH

+0

@LukeH Ihr Artikel ist ein bisschen waffle/akademischen. Ich mag die Java-Version mehr. –

5

Wenn Sie method2(Class1 c1) aufrufen, übergeben Sie eine Kopie der Referenz auf das Objekt, nicht das Objekt selbst (oder die Referenz darauf). Wenn Sie c1 = null festlegen, legen Sie fest, dass die Kopie der Referenz null ist, nicht das Objekt.

Sie können das Verhalten erhalten Sie, indem Sie Ihre Methodensignatur dazu erwarten:

method2(ref Class1 c1)

4

In C# werden Referenzen von Wert übergeben. Das heißt, method2 empfängt eine Kopie des Werts der Referenz auf c1.

In method2 wirkt sich die Einstellung c1 = null nur auf die lokale Kopie der Referenz aus.

Siehe this article for more info

1

Hoffentlich ein einfaches Bearbeiten des Codes können Sie zeigen, warum:

public class Class1 
{ 
    public int i; 
    public Class1() 
    { 
     i = 10; 
    }  

    public string method1() 
    { 
     return "str"; 
    } 
} 

public class Class2 
{ 
    public void method2(Class1 myLocalReference) 
    { 
     myLocalReference.i = 100; 
     myLocalReference = null; 
    } 
} 

void main() 
{ 
    Class1 c1 = new Class1(); 
    Class2 c2 = new Class2(); 
    c2.method2(c1); 
    Response.Write(c1.method1()); 
    Response.Write(c1.i.ToString()); 
} 

Ich denke, dass zeigt deutlich, dass die Referenz in Class2.method2 verwendet wird, ist nicht das gleiche wie die verwendeten in Haupt. c1 wird in main deklariert, wenn der Verweis auf Ihre Class1-Instanzen als Parameter im Methodenaufruf c2.method2(c1); verwendet wird, wird er in einen neuen lokalen Wert namens myLocalReference kopiert. Sie setzen dann myLocalReference = null; und innerhalb von Methode2 finden Sie, dass Response.Write(myLocalReference.method1()); oder Response.Write(myLocalReference.i.ToString()); würde ordnungsgemäß fehlschlagen. Wenn method2 die lokale Referenz verlässt, wird myLocalReference den Gültigkeitsbereich verlassen, und Sie kehren zu main zurück, wo die Referenz c1 vorhanden ist und unverändert bleibt, sodass die nachfolgenden Methoden von Response.Write erfolgreich sind.