Exercitarea - Utilizarea parametrilor de valoare și de referință
În C#, variabilele pot fi clasificate în două tipuri principale, tipuri de valori și tipuri de referință. Aceste tipuri descriu modul în care variabilele stochează valorile lor.
Tipurile de valori, cum intar fi , boolfloat, , double, și char conțin direct valori. Tipurile de referințe, cum stringar fi , arrayși obiectele (cum ar fi instanțele Random) nu stochează valorile direct. În schimb, tipurile de referințe stochează o adresă unde este stocată valoarea lor.
Parametrii transmiși de valoare și transmiși prin referință
Atunci când un argument este transmis unei metode, variabilele tipului de valoare au valorile copiate în metodă. Fiecare variabilă are propria copie a valorii, deci variabila originală nu este modificată.
Cu tipuri de referință, adresa valorii este transmisă în metodă. Variabila dată metodei face referire la valoarea de la acea adresă, astfel încât operațiunile cu acea variabilă afectează valoarea la care se face referire de cealaltă.
Notă
Este important să rețineți că string este un tip de referință, dar este invariabil. Aceasta înseamnă că, după ce i s-a atribuit o valoare, aceasta nu poate fi modificată. În C#, atunci când se utilizează metode și operatori pentru a modifica un șir, rezultatul returnat este de fapt un obiect șir nou.
În acest exercițiu, veți afla mai multe despre trecerea argumentelor pentru referințe și valori în metode.
Test treceți prin valoare
În Visual Studio Code Editor, ștergeți orice cod existent din exercițiile anterioare.
Introduceți următorul cod în Visual Studio Code Editor:
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}"); }Variabilele
a,bșicsunt transmise metodeiMultiply. Valorile variabilelor sunt imprimate în timpul executării metodei și se imprimă din nou după terminarea metodei.Numerele întregi sunt tipuri de valori, care au valorile lor copiate atunci când sunt transmise în metode. De ce crezi că va fi rezultatul
c?Salvați și rulați codul pentru a observa următoarea ieșire:
inside Multiply method: 3 x 4 = 12 global statement: 3 x 4 = 0Observați că valoarea
ceste modificată numai în cadrul metodeiMultiply. În afara metodei,cîși păstrează valoarea inițială.
Treceți testul prin referință
Ștergeți codul anterior din Visual Studio Code Editor.
Introduceți următorul cod în Visual Studio Code Editor:
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; } }Codul începe cu
arrayinițializat pentru a conține unele valori întregi. Valorile se afișează utilizândPrintArraymetoda. MetodaCleareste apelată pe matrice, apoi matricea se imprimă din nou.Matricele sunt tipuri de referință. Tipurile de referințe stochează adresa valorilor lor în memorie. Ce crezi că va fi rezultatul?
Salvați și rulați codul pentru a observa următoarea ieșire:
1 2 3 4 5 0 0 0 0 0Observați că matricea rămâne modificată în afara domeniului metodei
Clear. Acest lucru se întâmplă deoareceClearmetoda a actualizat valorile stocate la fiecare adresă.
Test cu șiruri
Mai devreme, ai aflat că șirurile sunt de un tip imutabil . Chiar dacă un șir este un tip de referință, valoarea sa nu poate fi modificată odată ce este atribuită, spre deosebire de un tablou. Este posibil să fi observat acest lucru dacă ați utilizat metode cum string.Replace ar fi sau string.ToUpper. În această activitate, veți afla să corectați o eroare comună găsită atunci când lucrați cu șiruri.
În Visual Studio Code Editor, ștergeți orice cod existent din exercițiile anterioare.
Introduceți următorul cod în Visual Studio Code Editor:
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}"); }Salvați și rulați codul pentru a observa următoarea ieșire:
Start: Healthy Middle: Unhealthy End: HealthySetHealthDacă metoda nu a generat starea, este posibil să fi presupus că metoda nu s-a executat corect. În schimb, s-a creat un șir nou cu valoarea "Nesănătos" și apoi s-a pierdut în domeniul metodei.Pentru a corecta această problemă, puteți modifica
SetHealthpentru a utiliza variabila de stare globală în schimb.Actualizați codul după cum urmează:
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}"); }În acest cod, suprascrieți variabila globală
statuscu noua valoare șir.Salvați și rulați codul pentru a observa următoarea ieșire:
Start: Healthy Middle: Unhealthy End: UnhealthyAcum șirul actualizat este capturat și stocat corect.
Recapitulare
Iată ce ați învățat despre tipul de valoare și parametrii de referință de până acum:
- Variabilele pot fi clasificate ca tipuri de valori și tipuri de referință.
- Tipurile de valori conțin direct valori și tipurile de referințe stochează adresa valorii.
- Metodele care utilizează argumente de tip valoare își creează propria copie a valorilor.
- Metodele care efectuează modificări asupra unui parametru matrice afectează matricea originală de intrare.
- Șirul este un tip de referință invariabil.
- Metodele care efectuează modificări într-un parametru șir nu afectează șirul original.