Övning – Använda parametrar för värde och referenstyp
I C# kan variabler kategoriseras i två huvudtyper, värdetyper och referenstyper. Dessa typer beskriver hur variabler lagrar sina värden.
Värdetyper som int, bool, float, doubleoch char direkt innehåller värden. Referenstyper som string, arrayoch objekt (till exempel instanser av Random) lagrar inte sina värden direkt. Referenstyper lagrar i stället en adress där deras värde lagras.
Parametrar som skickas genom värde och genom referens
När ett argument skickas till en metod kopieras värdetypvariablernas värden till metoden. Varje variabel har en egen kopia av värdet, så den ursprungliga variabeln ändras inte.
Med referenstyper skickas värdets adress till metoden. Variabeln som ges till metoden refererar till värdet på den adressen, så åtgärder på variabeln påverkar det värde som refereras av den andra.
Anmärkning
Det är viktigt att komma ihåg att det string är en referenstyp, men det är oföränderligt. Det innebär att när det har tilldelats ett värde kan det inte ändras. När metoder och operatorer används för att ändra en sträng i C# är resultatet som returneras faktiskt ett nytt strängobjekt.
I den här övningen får du lära dig mer om att skicka referens- och värdetypsargument till metoder.
Testa genomströmningsvärde
Ta bort befintlig kod från föregående övningar i Visual Studio Code-redigeraren.
Ange följande kod i Visual Studio Code-redigeraren:
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}"); }Variablerna
a,bochcskickas tillMultiplymetoden. Värdena för variablerna skrivs ut under metodkörningen och skrivs ut igen när metoden är klar.Heltal är värdetyper som får sina värden kopierade när de skickas till metoder. Vad tror du att utdata från
ckommer att bli?Spara och kör koden för att observera följande utdata:
inside Multiply method: 3 x 4 = 12 global statement: 3 x 4 = 0Observera att värdet på
cbara ändras inomMultiply-metoden. Utanför metodencbehåller det ursprungliga värdet.
Testpass av referens
Ta bort den tidigare koden från Visual Studio Code-redigeraren.
Ange följande kod i Visual Studio Code-redigeraren:
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; } }Koden börjar med att
arrayär initierad för att innehålla några heltalsvärden. Värdena visas med hjälp avPrintArraymetoden . MetodenClearanropas på matrisen och sedan skrivs matrisen ut igen.Matriser är referenstyper. Referenstyper lagrar adressen för sina värden i minnet. Vad tror du resultatet kommer att bli?
Spara och kör koden för att observera följande utdata:
1 2 3 4 5 0 0 0 0 0Observera att matrisen fortfarande ändras utanför metodomfånget
Clear. Detta beror på attClearmetoden uppdaterade värdena som lagras på varje adress.
Testa med strängar
Tidigare har du lärt dig att strängar är en oföränderlig typ. Även om en sträng är en referenstyp kan dess värde inte ändras när den har tilldelats, till skillnad från en matris. Du kanske har märkt detta om du har använt metoder som string.Replace eller string.ToUpper. I den här uppgiften lär du dig att korrigera ett vanligt fel som påträffas när du arbetar med strängar.
Ta bort befintlig kod från föregående övningar i Visual Studio Code-redigeraren.
Ange följande kod i Visual Studio Code-redigeraren:
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}"); }Spara och kör koden för att observera följande utdata:
Start: Healthy Middle: Unhealthy End: HealthySetHealthOm metoden inte angav statusen kan du ha antagit att metoden inte körs korrekt. I stället skapades en ny sträng med värdet "Ohälsosam" och förlorades sedan i metodomfånget.Du kan åtgärda problemet genom att ändra
SetHealthså att den globala statusvariabeln används i stället.Uppdatera koden på följande sätt:
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}"); }I den här koden skriver du över den globala
statusvariabeln med det nya strängvärdet.Spara och kör koden för att observera följande utdata:
Start: Healthy Middle: Unhealthy End: UnhealthyNu samlas den uppdaterade strängen in och lagras korrekt.
Sammanfattning
Här är vad du har lärt dig om parametrar för värdetyp och referenstyp hittills:
- Variabler kan kategoriseras som värdetyper och referenstyper.
- Värdetyper innehåller direkt värden och referenstyper lagrar värdets adress.
- Metoder som använder värdetypsargument skapar en egen kopia av värdena.
- Metoder som utför ändringar på en matrisparameter påverkar den ursprungliga indatamatrisen.
- Strängen är en oföränderlig referenstyp.
- Metoder som utför ändringar på en strängparameter påverkar inte den ursprungliga strängen.