2010-08-05 6 views
2

J'ai regardé les questions similaires et lu quelques articles. THis article a quelques photos qui le rend clair.En passant par référence et en utilisant la référence

SomeObject so = new SomeObject(); 
somefunction(so); 
Console.write(so.x); // will print 1 

SomeObject so1 = new SomeObject(); 
somefunctionByRef(so1); 
Console.write(so1.x); // will print 1 


static void somefunction(SomeObject so) 
{ 
    so.x = 1; 
} 

public void somefunctionByRef(ref SomeObject so) 
{ 
    so.x = 1; 
} 

Les deux méthodes ont le même effet sur ce type de référence. alors pourquoi choisir ref mot-clé pour les types de référence?

Est-ce une mauvaise pratique (peut-être fausse) d'utiliser somefunction (SomeObject so) et de modifier l'objet à l'intérieur de la méthode et attendre les changements sans utiliser le mot-clé ref?

Répondre

3

Le paramètre par défaut passant dans .Net est fait par valeur. Cela est vrai pour les types de valeur et les types de référence. La différence est qu'avec un type de référence, vous passez une référence à l'instance par valeur par rapport à l'objet réel.

L'effet est la référence de so dans la fonction originale et certainsFonctions sont indépendants. Changer l'instance à laquelle la référence fait référence n'a aucun effet sur l'autre. Cependant, parce qu'ils font référence au même objet, ils peuvent voir des mutations à cet objet fait par l'autre (ce qui est la raison pour laquelle x changements dans votre exemple)

SomeObject so = new SomeObject(); 
so.x = 42; 
somefunction(so); 
Console.Write(so.x); // will print 42 

static void somefunction(SomeObject so) { 
    so = new SomeObject(); 
    so.x = 13; 
} 

Le modificateur ref provoque le paramètre à passer par référence au lieu de la valeur . Effectivement il n'y a aucune copie de la référence, le so dans la fonction d'origine et d'appel sont la même référence. Donc réinitialiser l'un réinitialise l'autre

SomeObject so = new SomeObject(); 
so.x = 42; 
somefunction(ref so); 
Console.Write(so.x); // will print 13 

static void somefunction(ref SomeObject so) { 
    so = new SomeObject(); 
    so.x = 13; 
} 
1

Je n'utilise que ref pour les types sans référence, par ex. int, décimal etc.

jeter un oeil à this MSDN page pour un peu d'une explication plus claire, et un peu d'une chasse aux sorcières

1

classes sont déjà passé par référence (en termes non gérés est donc un pointeur vers un objet). Passer une référence vous permet de changer la variable sous-jacente (vous utilisez un pointeur sur un pointeur). Prenez ce code:

static void foo(SomeObject so) 
{ 
    so.x = 1; 
    so = null; 
} 

static void bar(ref SomeObject so) 
{ 
    so.x = 1; 
    so = null; 
} 

SomeObject so1 = new SomeObject(); 
foo(so1); 
Console.write(so1.x); // will print 1 
bar(so1); 
Console.write(so1.x); // crash 

La première méthode fonctionnera et vous imprimera 1 - attribuer ainsi null change juste une variable qui est à la fonction locale. Le second provoquera un crash (NullReferenceException) car so1 a été défini sur null.

+0

alors pourquoi choisir le mot clé ref pour les types de référence? – DarthVader

+0

alors quel est le point que vous essayez de faire? – ronaldwidha

+0

En utilisant 'ref', vous pouvez changer l'objet auquel une variable fait référence à partir d'une fonction différente. Notez l'affectation 'so = null;' –

0

Pour les types de référence, les paramètres par défaut sont transmis par référence, sauf indication contraire. Je pense que c'est une supposition suffisamment sûre que la plupart des développeurs .Net devraient savoir.

+1

Ils sont tous passés par _value_ par défaut. La _valeur_ diffère entre les types de valeur (l'objet) et les types de référence (une référence à l'objet). 'ref' et' out' permettent de passer par référence. –

Questions connexes