Share via


Passaggio di parametri di tipi di riferimento (Guida per programmatori C#)

Aggiornamento: novembre 2007

Una variabile di un tipo che rappresenta un riferimento non contiene direttamente dati, ma solo un riferimento a essi. Quando si passa un parametro associato a un tipo che rappresenta un riferimento per valore, è possibile modificare i dati associati al riferimento, ad esempio il valore del membro di una classe. Non è tuttavia possibile modificare il valore del riferimento stesso, ovvero non è possibile utilizzare tale riferimento per allocare memoria per una nuova classe e fare in modo che sia persistente anche all'esterno del blocco. In questo caso, è necessario passare il parametro utilizzando la parola chiave ref o out. Per semplicità, negli esempi che seguono viene utilizzata solo la parola chiave ref.

Esempio

Nell'esempio che segue viene illustrato il passaggio per valore del parametro associato a un tipo che rappresenta un riferimento arr al metodo Change. Poiché il parametro è un riferimento a arr, è possibile modificare il valore degli elementi della matrice. Il tentativo di riassegnare il parametro a una diversa posizione in memoria, tuttavia, è efficace solo all'interno del metodo e non ha alcun effetto sulla variabile originale arr.

class PassingRefByVal 
{
    static void Change(int[] pArray)
    {
        pArray[0] = 888;  // This change affects the original element.
        pArray = new int[5] {-3, -1, -2, -3, -4};   // This change is local.
        System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
    }

    static void Main() 
    {
        int[] arr = {1, 4, 5};
        System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr [0]);

        Change(arr);
        System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr [0]);
    }
}
/* Output:
    Inside Main, before calling the method, the first element is: 1
    Inside the method, the first element is: -3
    Inside Main, after calling the method, the first element is: 888
*/

Nell'esempio precedente la matrice arr, la quale rappresenta un tipo di riferimento, viene passata al metodo senza il parametro ref. In questo caso al metodo viene passata una copia del riferimento che punta a arr. L'output indica che il metodo ha la possibilità di modificare il contenuto di un elemento della matrice (da 1 a 888). L'allocazione di una nuova porzione di memoria utilizzando l'operatore new nel metodo Change, tuttavia, fa sì che la variabile pArray faccia riferimento a una nuova matrice. In questo modo eventuali modifiche successive non avranno effetto sulla matrice originale, arr, creata in Main. In effetti, in questo esempio vengono create due matrici: una in Main e una nel metodo Change.

Questo esempio è analogo all'esempio precedente, con la differenza che nell'intestazione e nella chiamata al metodo viene utilizzata la parola chiave ref. Eventuali modifiche apportate nel metodo avranno effetto sulle variabili originali del programma chiamante.

class PassingRefByRef 
{
    static void Change(ref int[] pArray)
    {
        // Both of the following changes will affect the original variables:
        pArray[0] = 888;
        pArray = new int[5] {-3, -1, -2, -3, -4};
        System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
    }

    static void Main() 
    {
        int[] arr = {1, 4, 5};
        System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr[0]);

        Change(ref arr);
        System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr[0]);
    }
}
/* Output:
    Inside Main, before calling the method, the first element is: 1
    Inside the method, the first element is: -3
    Inside Main, after calling the method, the first element is: -3
*/

Tutte le modifiche apportate all'interno del metodo hanno effetto sulla matrice originale in Main. In effetti, la matrice originale viene riallocata mediante l'operatore new. Dopo la chiamata al metodo Change, pertanto, i riferimenti a arr puntano alla matrice a cinque elementi creata nel metodo Change.

Lo scambio di stringhe è un buon esempio di passaggio di parametri associati a tipi che rappresentano un riferimento per riferimento. In questo esempio due stringhe, str1 e str2, vengono inizializzate in Main e passate al metodo SwapStrings come parametri modificati dalla parola chiave ref. Le due stringhe vengono scambiate all'interno del metodo e all'interno di Main.

 class SwappingStrings
 {
     static void SwapStrings(ref string s1, ref string s2)
     // The string parameter is passed by reference.
     // Any changes on parameters will affect the original variables.
     {
         string temp = s1;
         s1 = s2;
         s2 = temp;
         System.Console.WriteLine("Inside the method: {0} {1}", s1, s2);
     }

     static void Main()
     {
         string str1 = "John";
         string str2 = "Smith";
         System.Console.WriteLine("Inside Main, before swapping: {0} {1}", str1, str2);

         SwapStrings(ref str1, ref str2);   // Passing strings by reference
         System.Console.WriteLine("Inside Main, after swapping: {0} {1}", str1, str2);
     }
 }
 /* Output:
     Inside Main, before swapping: John Smith
     Inside the method: Smith John
     Inside Main, after swapping: Smith John
*/

In questo esempio è necessario passare i parametri per riferimento perché abbiano effetto sulle variabili del programma chiamante. Se si rimuove la parola chiave ref sia dall'intestazione del metodo che dalla chiamata al metodo, nel programma chiamante non avrà luogo alcuna modifica.

Per ulteriori informazioni sulle stringhe, vedere stringa.

Vedere anche

Concetti

Guida per programmatori C#

Riferimenti

Passaggio di parametri (Guida per programmatori C#)

Passaggio di matrici mediante ref e out (Guida per programmatori C#)

ref (Riferimenti per C#)

Tipi di riferimento (Riferimenti per C#)