ref (référence C#)

Le mot clé ref entraîne le passage d'un argument par référence, et non par valeur. La conséquence est que toute modification apportée au paramètre dans la méthode appelée est répercutée dans la méthode d'appel. Par exemple, si l'appelant passe une expression de variable locale ou d'une expression d'accès à un élément de tableau et que la méthode appelée remplace l'objet auquel fait référence le paramètre ref, la variable locale de l'appelant ou l'élément de tableau font désormais référence au nouvel objet.

Note

Ne confondez pas le concept de passage par référence avec celui de types de référence. Les deux concepts ne sont pas identiques. Un paramètre de méthode peut être modifié par ref, qu'il s'agisse d'un type valeur ou d'un type référence. Il n'y a aucun boxing d'un type valeur lorsqu'il est passé par référence.

Pour utiliser un paramètre ref, la définition de la méthode et la méthode d'appel doivent utiliser explicitement le mot clé ref, comme indiqué dans l'exemple suivant.

class RefExample
{
    static void Method(ref int i)
    {
        i = i + 44;
    }

    static void Main()
    {
        int val = 1;
        Method(ref val);
        Console.WriteLine(val);
        // Output: 45
    }
}

Un argument passé à un paramètre ref doit être initialisé avant d'être transmis. Cette obligation diffère des paramètres out, dont les arguments ne doivent pas être explicitement initialisés avant d'être passés. Pour plus d’informations, consultez out.

Les membres d'une classe ne peuvent pas avoir de signatures qui diffèrent uniquement par ref et out. Une erreur de compilation se produit si la seule différence entre deux membres d'un type est que l'un d'eux a un paramètre refet l'autre un paramètre out. Le code suivant, par exemple, ne se compile pas.

class CS0663_Example
{
    // Compiler error CS0663: "Cannot define overloaded 
    // methods that differ only on ref and out".
    public void SampleMethod(out int i) { }
    public void SampleMethod(ref int i) { }
}

Cependant, la surcharge peut avoir lieu quand une méthode a un paramètre ref ou out, et que l'autre a un paramètre de valeur, comme illustré dans l'exemple suivant.

class RefOverloadExample
{
    public void SampleMethod(int i) { }
    public void SampleMethod(ref int i) { }
}

Dans d'autres situations nécessitant une correspondance de signature, comme le masquage ou la substitution, ref et out font partie de la signature et ne correspondent pas l'un à l'autre.

Les propriétés ne sont pas des variables. Ce sont des méthodes et ne peuvent pas être passées aux paramètres ref.

Pour plus d’informations sur la manière de passer des tableaux, consultez Passage de tableaux à l’aide de paramètres ref et out.

Vous ne pouvez pas utiliser les mots clés ref et out pour les types de méthodes suivants :

  • Méthodes async, que vous définissez à l’aide du modificateur async.

  • Méthodes iterator, qui incluent une instruction yield return ou yield break.

Exemple

Les exemples précédents montrent ce qui se produit lors du passage de types valeur par référence. Vous pouvez également utiliser le mot clé ref pour passer les types référence. Le passage d'un type référence par référence permet à la méthode appelée de remplacer l'objet dans la méthode appelante à laquelle fait référence le paramètre de référence. L'emplacement de stockage de l'objet est passé à la méthode comme valeur du paramètre de référence. Si vous modifiez la valeur de l'emplacement de stockage du paramètre (pour pointer vers un nouvel objet), vous modifiez également l'emplacement de stockage auquel fait référence l'appelant. L'exemple suivant passe une instance d'un type référence en tant que paramètre ref. Pour plus d’informations sur la manière de passer des types référence par valeur et par référence, consultez Passage de paramètres de type référence .

class RefExample2
{
    static void Main()
    {
        // Declare an instance of Product and display its initial values.
        Product item = new Product("Fasteners", 54321);
        System.Console.WriteLine("Original values in Main.  Name: {0}, ID: {1}\n",
            item.ItemName, item.ItemID);

        // Pass the product instance to ChangeByReference.
        ChangeByReference(ref item);
        System.Console.WriteLine("Back in Main.  Name: {0}, ID: {1}\n",
            item.ItemName, item.ItemID);
    }

    static void ChangeByReference(ref Product itemRef)
    {
        // Change the address that is stored in the itemRef parameter.   
        itemRef = new Product("Stapler", 99999);

        // You can change the value of one of the properties of
        // itemRef. The change happens to item in Main as well.
        itemRef.ItemID = 12345;
    }
}

class Product
{
    public Product(string name, int newID)
    {
        ItemName = name;
        ItemID = newID;
    }

    public string ItemName { get; set; }
    public int ItemID { get; set; }
}
// Output: 
//        Original values in Main.  Name: Fasteners, ID: 54321
//    
//        Back in Main.  Name: Stapler, ID: 12345

Spécification du langage C#

Pour plus d'informations, voir la spécification du langage C#. La spécification du langage est la source de référence pour la syntaxe C# et son utilisation.

Voir aussi

Informations de référence sur C#
Guide de programmation C#
Passage de paramètres
Paramètres de méthodes
Mots clés C#