2010-05-29 11 views
4

J'ai écrit quelques blocs de code sur la déclaration ref -out. Je pense que ref est le plus utile. D'accord. pourquoi je dois utiliser dehors. Je peux utiliser toujours ref chaque fois:Pourquoi utiliser "out" au lieu de ref?

namespace out_ref 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      sinifA sinif = new sinifA(); 
      int test = 100; 
      sinif.MethodA(out test); 
      Console.WriteLine(test.ToString()); 

      sinif.MethodB(ref test); 
      Console.WriteLine(test.ToString()); 
      Console.ReadKey(); 
     } 
    } 

    class sinifA 
    { 

     public void MethodA(out int a) 
     { 
      a = 200; 
     } 

     int _b; 
     public void MethodB(ref int b) 
     { 
      _b = b; 
      b = 2*b; 
     } 
    } 

} 

Répondre

13

Oui, vous pouvez utiliser ref à chaque fois, mais ils ont des objectifs différents. ref est utilisé lorsqu'un paramètre est à la fois une entrée et une sortie. out est utilisé lorsque le paramètre est uniquement une sortie. Il peut être utilisé pour transmettre une entrée, mais cela permet à l'utilisateur d'une fonction de ne pas déclarer une instance avant d'utiliser la fonction car vous êtes en train de dire que vous garantirez qu'une instance est créée. Il est particulièrement utile dans le modèle TryXXX lorsque vous recevez une valeur d'une collection

+3

De plus, un paramètre out doit être initialisé par la fonction qui le requiert, sinon vous obtenez des erreurs de compilation, ce qui est une bonne chose. –

+0

L'appelant doit déclarer la variable, mais n'a pas besoin de l'initialiser. – TrueWill

6

Lorsque vous avez un paramètre associé à out, vous n'avez pas besoin de l'initialiser avant de le transmettre à la méthode l'accepte.

The out keyword causes arguments to be passed by reference. 
This is like the ref keyword, except that ref requires that the variable be initialized 
before it is passed. 

De: http://msdn.microsoft.com/en-us/library/ee332485.aspx

3

Un paramètre out est garanti d'être initialisé au cours de la fonction. Cela fournit un contrat plus strict à votre interlocuteur. Il vous permet également d'écrire du code comme ceci:

int i; 
MyFunc(out i); 
.. < use i > .. 

sans obtenir une erreur de compilation pour une variable non initialisée.

0

Paramètres Out

En plus de passer des valeurs par référence, vous pouvez également spécifier qu'un paramètre donné est un paramètre sur en utilisant le mot-clef, qui est utilisé de la même manière que le mot-clé ref (en tant que modificateur au paramètre dans la définition de fonction et dans l'appel de fonction). En effet, cela vous donne presque exactement le même comportement qu'un paramètre de référence en ce que la valeur du paramètre à la fin de l'exécution de la fonction est renvoyée à la variable utilisée dans l'appel de fonction. Cependant, il existe d'importantes différences:

  1. considérant qu'il est illégal d'utiliser une variable non affectée comme paramètre de référence, vous pouvez utiliser une variable non affectée comme paramètre sur
  2. Un paramètre out doit être traité comme un valeur non affectée par la fonction qui l'utilise.

Cela signifie que pendant qu'il est permis d'appeler le code à utiliser une variable affectée en tant que paramètre de sortie, la valeur stockée dans cette variable est perdue lorsque la fonction est exécutée. Par exemple, considérons une extension de la fonction MaxValue() présentée plus haut, qui renvoie la valeur maximale d'un tableau. Modifiez légèrement la fonction afin d'obtenir l'indice de l'élément avec la valeur maximale dans le tableau. Pour garder les choses simples, obtenez seulement l'indice de la première occurrence de cette valeur lorsqu'il y a plusieurs éléments avec la valeur maximale.Pour ce faire, vous ajoutez un paramètre en modifiant la fonction comme suit:

static int MaxValue(int[] intArray, out int maxIndex) 

{int maxVal = intArray [0]; maxIndex = 0; for (int i = 1; i < intArray.Length; i ++) { if (intArray [i]> maxVal) { maxVal = intArray [i]; maxIndex = i; } } return maxVal; }

Vous pouvez utiliser cette fonction comme indiqué ici:

int[] myArray = {1, 8, 3, 6, 2, 5, 9, 3, 0, 2}; 

int maxindex; Console.WriteLine ("La valeur maximale dans myArray est {0}", MaxValue (myArray, out maxIndex)); Console.WriteLine ("La première occurrence de cette valeur est à l'élément {0}", maxIndex + 1);

Il en résulte dans ce qui suit:

La valeur maximale dans MonTableau est 9

La première apparition de cette valeur est à l'élément 7

One ont été ajoutées à la La valeur de maxIndex est renvoyée ici lorsqu'elle est affichée à l'écran. Ceci est à traduire l'indice en une forme plus facile à lire, de sorte que le premier élément du tableau est désignée comme élément 1, au lieu de l'élément 0.

1

ref et out est traitée de la même manière interne, ils sommes tous les deux passés une variable par référence. La différence est dans la sémantique d'initialisation, qui est responsable de s'assurer que la variable a une valeur de début valide, et elle est appliquée par le compilateur.

Avec les paramètres out, c'est la méthode que vous appelez. Quelle que soit la valeur de la variable que vous passez par référence avant d'appeler la méthode, cela n'a pas d'importance. Le compilateur se plaindra si la méthode que vous appelez a un chemin d'exécution qui ne parvient pas à définir une nouvelle valeur pour son paramètre. Cela signifie que toute valeur contenue dans la variable avant l'appel de la méthode est garantie pour être écrasée, même si elle a la même valeur. Avec ref paramètres, c'est la méthode qui appelle. La valeur de la variable sera transmise à la méthode appelée, qui peut alors inspecter son paramètre et éventuellement le modifier. Le compilateur se plaindra de la méthode que les appels n'initialise pas la variable avec une valeur avant de faire l'appel.

Donc, fondamentalement, tout dépend de ce que le compilateur va se plaindre. Est-ce le code appelant qui doit s'assurer qu'il y a une valeur dans la variable ou est-ce le code appelé.

Questions connexes