Esercizio - Usare i parametri di tipo riferimento e valore
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
Nell'editor di Visual Studio Code eliminare qualsiasi codice esistente dagli esercizi precedenti.
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,becvengono passate alMultiplymetodo . 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
csarà?Salvare ed eseguire il codice per osservare l'output seguente:
inside Multiply method: 3 x 4 = 12 global statement: 3 x 4 = 0Si noti che il valore di
cviene modificato solo all'interno delMultiplymetodo . Al di fuori del metodo,cmantiene il valore originale.
Superamento del test per riferimento
Eliminare il codice precedente dall'editor di Visual Studio Code.
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
arrayinizializzato per contenere alcuni valori integer. I valori vengono visualizzati usando ilPrintArraymetodo . IlClearmetodo 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?
Salvare ed eseguire il codice per osservare l'output seguente:
1 2 3 4 5 0 0 0 0 0Si noti che la matrice rimane modificata all'esterno dell'ambito del
Clearmetodo. Ciò si verifica perché ilClearmetodo 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.
Nell'editor di Visual Studio Code eliminare qualsiasi codice esistente dagli esercizi precedenti.
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}"); }Salvare ed eseguire il codice per osservare l'output seguente:
Start: Healthy Middle: Unhealthy End: HealthySe il
SetHealthmetodo 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
SetHealthper usare invece la variabile di stato globale.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
statuscon il nuovo valore stringa.Salvare ed eseguire il codice per osservare l'output seguente:
Start: Healthy Middle: Unhealthy End: UnhealthyOra 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.