Question

Je recherche une réponse claire, concise et précise.

Idéalement comme réponse réelle, bien que les liens vers de bonnes explications soient les bienvenus.

Cela s'applique également à VB.Net, mais les mots-clés sont différents : ByRef et ByVal.

Était-ce utile?

La solution

Par défaut (en C#), passer un objet à une fonction transmet en fait 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"

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

Les deux out et ref se comportent de manière identique à une légère différence près : ref les paramètres doivent être initialisés avant l'appel, tandis que out les paramètres peuvent être non initialisés.Par extension, ref les paramètres sont garantis d'être initialisés au début de la méthode, tandis que out les paramètres 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 souligne, la différence entre out et ref n'est appliqué que par le compilateur C#, pas par le CLR.Autant que je sache, VB n'a pas d'équivalent pour out et met en œuvre ref (comme ByRef) uniquement, correspondant au support du CLR.

Autres conseils

Une remarque supplémentaire sur la référence vs.dehors:La distinction entre les deux est renforcé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 uniquement par un out ou un 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) {}

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 à passer :

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

Une de mes propres questions sur stackoverflow traite également de ce sujet.
Il gère environ "passer par référence" et "passer par valeur" dans différents types de langues, c# est inclus alors peut-être pourrez-vous également y trouver des informations supplémentaires.

En gros, cela revient à :

  • réf:le paramètre avec le mot clé ref sera passé par référence
  • dehors:le paramètre avec le mot clé out sera traité comme un paramètre de sortie

mais c'est vraiment la réponse la plus élémentaire que vous puissiez donner, car elle est un peu plus complexe que ce qui est indiqué ici

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top