2008-08-16 7 views

Répondre

24

Par défaut (en C#), le passage d'un objet à une fonction transmet une copie de la référence à cet objet. La modification du paramètre lui-même ne modifie que la valeur du paramètre et non la variable spécifiée.

void Test1(string param) 
{ 
    param = "new value"; 
} 

string s1 = "initial value"; 
Test1(s1); 
// s1 == "initial value" 

Utilisation out ou ref passe une référence à la variable spécifiée dans l'appel à la fonction. Toute modification de la valeur d'un paramètre out ou ref sera renvoyée à l'appelant.

Les deux out et ref comportent de manière identique, sauf pour une légère différence: ref paramètres doivent être initialisées avant d'appeler, alors que out paramètres peuvent être uninitialised. Par extension, les paramètres ref sont garantis être initialisés au début de la méthode, tandis que les paramètres out sont traités comme non initialisés.

void Test2(ref string param) 
{ 
    param = "new value"; 
} 

void Test3(out string param) 
{ 
    // Use of param here will not compile 
    param = "another value"; 
} 

string s2 = "initial value"; 
string s3; 
Test2(ref s2); 
// s2 == "new value" 
// Test2(ref s3); // Passing ref s3 will not compile 
Test3(out s2); 
// s2 == "another value" 
Test3(out s3); 
// s3 == "another value" 

Modifier: Comme dp rappelle, la différence entre out et ref n'est appliquée par le compilateur C#, non par le CLR. Pour autant que je sache, VB n'a pas d'équivalent pour out et implémente ref (comme ByRef) uniquement, correspondant au support du CLR.

+0

"copie de la référence à cet objet" ou "référence à la copie de cet objet"? – bjan

3

out signifie que le paramètre sera initialisé par la méthode:

int result; //not initialised 

if(int.TryParse("123", out result)) 
    //result is now 123 
else 
    //if TryParse failed result has still be 
    // initialised to its default value (0) 

ref forcera la référence sous-jacente à transmettre:

void ChangeMyClass1(MyClass input) { 
    input.MyProperty = "changed by 1"; 
    input = null; 
    //can't see input anymore ... 
    // I've only nulled my local scope's reference 
} 

void ChangeMyClass2(ref MyClass input) { 
    input.MyProperty = "changed by 2"; 
    input = null; 
    //the passed reference is now null too. 
} 

MyClass tester = new MyClass { MyProperty = "initial value" }; 

ChangeMyClass1(tester); 
// now tester.MyProperty is "changed by 1" 

ChangeMyClass2(ref tester); 
// now tester is null 
2

Un de mes propres questions poignées à stackoverflow ce sujet aussi.
Il gère environ "pass by reference" and "pass by value" dans différents types de langues, c# is included alors peut-être vous pouvez y trouver des informations supplémentaires.

Fondamentalement, il se résume à:

  • ref: le paramètre avec le mot-clé ref sera transmis par référence
  • sur: le paramètre avec le mot-clé sur sera traitée comme un paramètre de sortie

mais c'est vraiment la réponse la plus fondamentale que vous pouvez donner, car il est un peu plus complexe qu'il est indiqué ici

7

Une note supplémentaire sur ref et out: La distinction entre les deux est imposée par le compilateur C#. Le CLR ne fait pas de distinction entre out et ref.Cela signifie que vous ne pouvez pas avoir deux méthodes dont les signatures diffèrent seulement par un out ou ref

void foo(int value) {} 

// Only one of the following would be allowed 

// valid to overload with ref 
void foo(ref int value) {} 

// OR with out 
void foo(out int value) {} 
Questions connexes