Condividi tramite


ref (Riferimenti per C#)

La parola chiave ref fa sì che un argomento sia passati per riferimento, non per valore. L'effetto del passaggio per riferimento è che qualsiasi modifica al parametro nel metodo chiamato viene riflessa nel metodo di chiamata. Ad esempio, se il chiamante passa un'espressione variabile locale o un'espressione di accesso dell'elemento della matrice e il metodo chiamato sostituisce l'oggetto a cui fa riferimento il parametro ref, l'elemento della matrice o una variabile locale del chiamante fa ora riferimento al nuovo oggetto.

Nota

Non confondere il concetto di passaggio per riferimento con il concetto di tipi di riferimento.I due concetti non sono uguali.Un parametro di metodo può essere modificato da ref che si tratti di un tipo di valore o di un tipo di riferimento.Non viene eseguito il boxing di un tipo di valore quando viene passato per riferimento.

Per usare un parametro ref, la definizione del metodo e il metodo chiamante devono usare in modo esplicito la parola chiave ref, come illustrato nell'esempio seguente.

    class RefExample
    {
        static void Method(ref int i)
        {
            // Rest the mouse pointer over i to verify that it is an int. 
            // The following statement would cause a compiler error if i 
            // were boxed as an object.
            i = i + 44;
        }

        static void Main()
        {
            int val = 1;
            Method(ref val);
            Console.WriteLine(val);

            // Output: 45
        }
    }

Un argomento passato a un parametro ref deve essere inizializzato prima di essere passato. Questo comportamento è diverso dai parametri out, i cui argomenti non è essere inizializzati in modo esplicito prima di essere passati. Per altre informazioni, vedere out.

I membri di una classe non possono avere firme che differiscono solo per ref e out. Un errore del compilatore si verifica se l'unica differenza tra due membri di un tipo è che uno di essi ha un parametro ref e l'altro ha un parametro out. Il codice seguente, ad esempio, non viene compilato.

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) { }
}

Tuttavia, l'overload può essere eseguito quando un metodo ha un parametro ref o out e l'altro ha un parametro di valore, come illustrato nell'esempio seguente.

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

In altre situazioni che richiedono la firma corrispondente, ad esempio nascondere o sottoporre a override, ref e out fanno parte della firma e non sono corrispondenti tra loro.

Le proprietà non sono variabili. Sono metodi e non possono essere passate ai parametri ref.

Per informazioni su come passare le matrici, vedere Passaggio di matrici mediante ref e out (Guida per programmatori C#).

Non è possibile usare le parole chiave ref e out per i seguenti tipi di metodi:

  • Metodi Async, definiti usando il modificatore async.

  • Metodi Iterator, che comprendono un'istruzione yield return o yield break.

Esempio

Negli esempi precedenti viene illustrato cosa accade quando si passano i tipi di valore per riferimento. È anche possibile usare la parola chiave ref per passare i tipi di riferimento. Il passaggio di un tipo di riferimento per riferimento consente al metodo chiamato di sostituire l'oggetto nel metodo di chiamata a cui fa riferimento il parametro referenziato. Il percorso di archiviazione dell'oggetto viene passato al metodo come valore del parametro referenziato. Se si modifica il valore nella posizione di archiviazione del parametro (in modo che punti a un nuovo oggetto), è anche possibile modificare il percorso di archiviazione a cui fa riferimento il chiamante. Nell'esempio seguente viene passata un'istanza di un tipo di riferimento come parametro ref. Per altre informazioni su come passare i tipi di riferimento per valore e per riferimento, vedere Passaggio di parametri di tipi di riferimento (Guida per programmatori C#).

class RefExample2
{
    static void ChangeByReference(ref Product itemRef)
    {
        // The following line changes the address that is stored in   
        // parameter itemRef. Because itemRef is a ref parameter, the 
        // address that is stored in variable item in Main also is changed.
        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;
    }

    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);

        // Send item to ChangeByReference as a ref argument.
        ChangeByReference(ref item);
        System.Console.WriteLine("Back in Main.  Name: {0}, ID: {1}\n",
            item.ItemName, item.ItemID);
    }
}

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

Specifiche del linguaggio C#

Per altre informazioni, vedere la Specifiche del linguaggio C#. La specifica del linguaggio costituisce il riferimento ufficiale principale per la sintassi e l'uso di C#.

Vedere anche

Riferimenti

Passaggio di parametri (Guida per programmatori C#)

Parametri di metodo (Riferimenti per C#)

Parole chiave di C#

Concetti

Guida per programmatori C#

Altre risorse

Riferimenti per C#