2010-12-08 10 views
1

Ich habe mein Problem im folgenden Codeausschnitt zusammengefasst.Werttyp und Ref Typ

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication13 
{ 
    public class Student 
    { 
     public int Marks { get; set; } 
     public Student(int marks) 
     { 
      this.Marks = marks; 

     } 
     public void AssignMarks(Student st) 
     { 
      st = null; 
     } 
     public void AssignMarks(ref Student st) 
     { 
      st = null; 
     } 
    } 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Student st = new Student(50); 
      st.AssignMarks(st); 
      Console.WriteLine(st.Marks); 
      Student st1 = new Student(50); 
      st.AssignMarks(ref st1); // NullReferenceException 
      Console.WriteLine(st1.Marks); 
     } 
    } 
} 

Warum erhalte ich Nullreferenceexception Ausnahme auf die Zeile mit dem **

markiert
+0

gut, die Art der Ausnahme könnte helfen – BlackICE

+0

Ich habe meine Frage bearbeitet.Ich bekomme NullReferenceException –

+0

@cdhowie: Danke cdhowie zum Bearbeiten meiner Frage. –

Antwort

5

Sie sind eigentlich immer die Ausnahme auf dem WriteLine Anruf., (Ich es versucht)

Da st1ref übergeben wird, die Variable, die Sie null passieren wird.

Ein ref Parameter ist eine Referenz auf eine Variable, keine Referenz auf ein Objekt.
Wenn eine Methode ihren ref-Parameter so ändert, dass sie auf ein anderes Objekt zeigt, wird daher die Variable, deren Referenz übergeben wurde, geändert.

+0

+1 für eine tiefergehende Erklärung. Wie einige es ausdrücken möchten, verhält sich der Parameter 'ref' wie ein * Alias ​​* für die ursprüngliche Variable an der Aufrufstelle. –

1

Sind Sie sicher, dass Sie keinen NullReferenceException auf der Linie unten bekommen (wie ich zu sehen bin)?

Dies wird dadurch verursacht, dass im Körper von AssignMarks(ref Student st) der Verweis st1 auf null gesetzt ist.

1

Sie erhalten Nullreferenceexception in der nächsten Zeile (Console.WriteLine(st1.Marks);), weil st1 nach AssignMarks(ref Student st1)

1

Ausführung null Sie sollten über Valuetype/Referenztyp und Stapel/Haufen lesen.

Hier ist Student ein Referenztyp, also wird Ihr Objekt in Heap gespeichert. Der Zeiger auf dieses Objekt liegt in Stack (da es eine Variable ist).

"Method - 1"

Wenn Sie das Objekt in dem ersten Methode übergeben (ohne ref), die Sie senden die Zeiger, die in Heap zu einem gewissen Adresse Punkte (wieder, da Student des Referenztypen ist). Dieser Zeiger wird in das Argument "kopiert" und ist nur für die Methode lokal. Nun kann die Methode auf diesen Speicherort zugreifen und den in dieser Adresse gespeicherten Wert "ändern".

als unten,

public void AssignMarks(Student st) 
     { 
      st.Marks=100; 
     } 

In diesem Fall Console.WriteLine in Program.Main Verfahren wird pring 100 !!!

Kommen wir zu Ihrer ersten Methode zurück. Der Zeiger wird im Argument Ihrer Methode "kopiert". Diese lokale Kopie zeigt 'st = null' auf "neuen" Speicherort in Heap, und der ursprüngliche Speicherort verbleibt wie es ist. So, wenn der Anruf zurückkehrt. Ihr Objekt bleibt gleich.

„Method - 2“

Auf der anderen Seite, wenn Sie dieses Argument als ‚ref‘ übergeben, es Zeiger auf Ihre ursprüngliche Variable tatsächlich sendet (Verhalten für ValyeType und Reference gleich bleibt). In diesem Fall hat die Methode Zugriff auf den Speicherort der Variablen selbst (nicht auf den Wert, auf den sie verweist). Wenn also die Methode irgendetwas in diesem Argument ändert, wird sie in der aufrufenden Methode unverändert wiedergegeben. Muss sein, oder?In jedem Sinne wird auf denselben Speicherort von verschiedenen Orten und verschiedenen Variablen zugegriffen.

Da Sie Ihrem Objekt explizit 'null' zugewiesen haben. Es wird Null Reference-Ausnahme ausgelöst.

Hoffe, das würde helfen.

Verwandte Themen