Esercizio - Usare i parametri di tipo riferimento e valore

Completato

In C# le variabili possono essere classificate in due tipi principali, tipi valore e tipi riferimento. Questi tipi descrivono il modo in cui le variabili archiviano i valori.

I tipi valore, ad esempio int, boolfloat, double, e char contengono direttamente valori. I tipi di riferimento come string, array e oggetti (come le istanze di Random) non archiviano i loro valori direttamente. I tipi di riferimento archiviano invece un indirizzo in cui è archiviato il relativo valore.

Parametri passati per valore e passati per riferimento

Quando un argomento viene passato a un metodo, le variabili di tipo valore hanno i relativi valori copiati nel metodo . Ogni variabile ha una propria copia del valore, quindi la variabile originale non viene modificata.

Con i tipi riferimento, l'indirizzo del valore viene passato al metodo . La variabile specificata al metodo fa riferimento al valore in corrispondenza di tale indirizzo, pertanto le operazioni su tale variabile influiscono sul valore a cui fa riferimento l'altro.

Annotazioni

È importante ricordare che string è un tipo riferimento, ma non modificabile. Ciò significa che una volta assegnato un valore, non può essere modificato. In C#, quando vengono usati metodi e operatori per modificare una stringa, il risultato restituito è effettivamente un nuovo oggetto stringa.

In questo esercizio verranno fornite altre informazioni sul passaggio di argomenti di tipo riferimento e valore nei metodi.

Superamento del test per valore

  1. Nell'editor di Visual Studio Code eliminare qualsiasi codice esistente dagli esercizi precedenti.

  2. Immettere il codice seguente nell'editor di Visual Studio Code:

    int a = 3;
    int b = 4;
    int c = 0;
    
    Multiply(a, b, c);
    Console.WriteLine($"global statement: {a} x {b} = {c}");
    
    void Multiply(int a, int b, int c) 
    {
        c = a * b;
        Console.WriteLine($"inside Multiply method: {a} x {b} = {c}");
    }
    

    Le variabili a, be c vengono passate al Multiply metodo . I valori delle variabili vengono stampati durante l'esecuzione del metodo e stampati di nuovo dopo il completamento del metodo.

    I numeri interi sono tipi valore, che hanno i relativi valori copiati quando vengono passati ai metodi. Che cosa pensi che l'output di c sarà?

  3. Salvare ed eseguire il codice per osservare l'output seguente:

    inside Multiply method: 3 x 4 = 12
    global statement: 3 x 4 = 0
    

    Si noti che il valore di c viene modificato solo all'interno del Multiply metodo . Al di fuori del metodo, c mantiene il valore originale.

Superamento del test per riferimento

  1. Eliminare il codice precedente dall'editor di Visual Studio Code.

  2. Immettere il codice seguente nell'editor di Visual Studio Code:

    int[] array = {1, 2, 3, 4, 5};
    
    PrintArray(array);
    Clear(array);
    PrintArray(array);
    
    void PrintArray(int[] array) 
    {
        foreach (int a in array) 
        {
            Console.Write($"{a} ");
        }
        Console.WriteLine();
    }
    
    void Clear(int[] array) 
    {
        for (int i = 0; i < array.Length; i++) 
        {
            array[i] = 0;
        }
    }
    

    Il codice inizia con array inizializzato per contenere alcuni valori integer. I valori vengono visualizzati usando il PrintArray metodo . Il Clear metodo viene chiamato sulla matrice e quindi la matrice viene stampata di nuovo.

    Le matrici sono tipi di riferimento. I tipi di riferimento archiviano l'indirizzo dei relativi valori in memoria. Quale si ritiene che possa essere l'output?

  3. Salvare ed eseguire il codice per osservare l'output seguente:

    1 2 3 4 5 
    0 0 0 0 0
    

    Si noti che la matrice rimane modificata all'esterno dell'ambito del Clear metodo. Ciò si verifica perché il Clear metodo ha aggiornato i valori archiviati in ogni indirizzo.

Test con stringhe

In precedenza si è appreso che le stringhe sono un tipo non modificabile . Anche se una stringa è un tipo riferimento, il relativo valore non può essere modificato una volta assegnato, a differenza di una matrice. Questo potrebbe essere stato notato se sono stati usati metodi come string.Replace o string.ToUpper. In questa attività si apprenderà come correggere un errore comune rilevato durante l'uso delle stringhe.

  1. Nell'editor di Visual Studio Code eliminare qualsiasi codice esistente dagli esercizi precedenti.

  2. Immettere il codice seguente nell'editor di Visual Studio Code:

    string status = "Healthy";
    
    Console.WriteLine($"Start: {status}");
    SetHealth(status, false);
    Console.WriteLine($"End: {status}");
    
    void SetHealth(string status, bool isHealthy) 
    {
        status = (isHealthy ? "Healthy" : "Unhealthy");
        Console.WriteLine($"Middle: {status}");
    }
    
  3. Salvare ed eseguire il codice per osservare l'output seguente:

    Start: Healthy
    Middle: Unhealthy
    End: Healthy
    

    Se il SetHealth metodo non ha restituito lo stato, è possibile che il metodo non sia stato eseguito correttamente. Invece, è stata creata una nuova stringa con il valore "Non salutare" e quindi è stata persa nell'ambito del metodo.

    Per risolvere il problema, è possibile modificare SetHealth per usare invece la variabile di stato globale.

  4. Aggiornare il codice come segue:

    string status = "Healthy";
    
    Console.WriteLine($"Start: {status}");
    SetHealth(false);
    Console.WriteLine($"End: {status}");
    
    void SetHealth(bool isHealthy) 
    {
        status = (isHealthy ? "Healthy" : "Unhealthy");
        Console.WriteLine($"Middle: {status}");
    }
    

    In questo codice si sovrascrive la variabile globale status con il nuovo valore stringa.

  5. Salvare ed eseguire il codice per osservare l'output seguente:

    Start: Healthy
    Middle: Unhealthy
    End: Unhealthy
    

    Ora la stringa aggiornata viene acquisita e archiviata correttamente.

Riepilogo

Ecco quanto appreso sui parametri del tipo di valore e del tipo di riferimento finora:

  • Le variabili possono essere classificate come tipi di valore e tipi riferimento.
  • I tipi valore contengono direttamente valori e i tipi riferimento archiviano l'indirizzo del valore.
  • I metodi che usano argomenti di tipo valore creano la propria copia dei valori.
  • I metodi che eseguono modifiche su un parametro di matrice influiscono sulla matrice di input originale.
  • String è un tipo riferimento non modificabile.
  • I metodi che eseguono modifiche su un parametro stringa non influiscono sulla stringa originale.