2010-12-08 5 views
1

J'ai résumé mon problème dans l'extrait de code suivant.Type de valeur et type de référence

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); 
     } 
    } 
} 

Pourquoi ai-je exception NullReferenceException sur la ligne marquée avec le **

+0

bien, le type d'exception pourrait aider – BlackICE

+0

J'ai édité ma question.Je reçois NullReferenceException –

+0

@cdhowie: Merci cdhowie pour éditer ma question. –

Répondre

5

Vous obtenez en fait l'exception de l'appel WriteLine., (Je l'ai essayé)

Parce que st1 est passé ref, la variable que vous passez devient null.

Un paramètre ref est une référence à une variable , et non une référence à un objet.
Par conséquent, si une méthode modifie son paramètre ref pour pointer vers un objet différent, la variable dont la référence a été transmise sera modifiée.

+0

+1 pour fournir une explication plus approfondie. Comme certains aiment l'exprimer, le paramètre 'ref' agit comme un * alias * pour la variable d'origine sur le site d'appel. –

1

Etes-vous sûr que vous n'êtes pas obtenir un NullReferenceException sur la ligne ci-dessous (que je vois)?

Cela est dû au fait que la référence st1 est définie sur null dans le corps de AssignMarks(ref Student st).

1

Vous obtenez NullReferenceException sur la ligne suivante (Console.WriteLine(st1.Marks);) parce que st1 est nul après l'exécution AssignMarks(ref Student st1)

1

Vous devriez lire sur ValueType/Référence Type et pile/Heap.

Ici, Student est un type de référence, donc votre objet est stocké dans Heap. Le pointeur vers cet objet se trouve dans Stack (puisqu'il s'agit d'une variable).

« Méthode - 1 »

Lorsque vous passez l'objet dans la première méthode (sans ref), vous envoyez le pointeur qui pointe vers une adresse Heap (encore une fois, puisque l'étudiant est de type de référence). Ce pointeur est "copié" dans l'argument et n'est local que pour la méthode. Maintenant, la méthode peut accéder à cet emplacement de mémoire et "changer" la valeur stockée dans cette adresse.

comme ci-dessous,

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

Dans ce cas, la méthode WriteLine Program.Main sera Pring 100 !!!

Revenons à votre première méthode. Le pointeur est "copié" dans l'argument de votre méthode. En faisant, 'st = null', cette copie locale pointe vers "nouveau" emplacement de mémoire dans Heap et l'emplacement de mémoire d'origine reste tel quel. Ainsi, lorsque l'appel revient. Votre objet reste le même.

« Méthode - 2 »

D'autre part, lorsque vous passez cet argument comme « ref », il envoie effectivement pointeur à votre variable d'origine (comportement reste identique pour ValyeType et referenceType). Dans ce cas, la méthode a accès à l'emplacement mémoire de la variable elle-même (et non à la valeur vers laquelle elle pointe). Ainsi, si la méthode change quoi que ce soit dans cet argument, elle est reflétée telle quelle dans la méthode appelante. Doit être, non?Dans tous les sens, c'est le même emplacement de mémoire accessible à partir de différents endroits et de différentes variables.

Puisque vous avez explicitement affecté 'null' à votre objet. Il lance l'exception Null Reference.

Espérons que cela aiderait.

Questions connexes