Oefening: waarde- en verwijzingstypeparameters gebruiken

Voltooid

In C# kunnen variabelen worden onderverdeeld in twee hoofdtypen, waardetypen en referentietypen. Deze typen beschrijven hoe variabelen hun waarden opslaan.

Waardetypen zoals int, bool, float, double, en char bevatten rechtstreeks waarden. Verwijzingstypen zoals string, arrayen objecten (zoals exemplaren van Random) slaan hun waarden niet rechtstreeks op. In plaats daarvan slaan verwijzingstypen een adres op waarin hun waarde wordt opgeslagen.

Parameters doorgegeven door waarde en doorgegeven door verwijzing

Wanneer een argument wordt doorgegeven aan een methode, worden de waarden van een waardetypevariabele naar de methode gekopieerd. Elke variabele heeft een eigen kopie van de waarde, dus de oorspronkelijke variabele wordt niet gewijzigd.

Met verwijzingstypen wordt het adres van de waarde doorgegeven aan de methode. De variabele die aan de methode wordt gegeven, verwijst naar de waarde op dat adres, zodat bewerkingen op die variabele van invloed zijn op de waarde waarnaar wordt verwezen door de andere.

Opmerking

Het is belangrijk om te onthouden dat string dit een verwijzingstype is, maar het is onveranderbaar. Dit betekent dat wanneer een waarde is toegewezen, deze niet kan worden gewijzigd. Wanneer in C# methoden en operators worden gebruikt om een tekenreeks te wijzigen, is het resultaat dat wordt geretourneerd, eigenlijk een nieuw tekenreeksobject.

In deze oefening leert u meer over het doorgeven van verwijzings- en waardetypeargumenten aan methoden.

Pass by-waarde testen

  1. Verwijder in de Visual Studio Code-editor alle bestaande code uit de vorige oefeningen.

  2. Voer de volgende code in de Visual Studio Code-editor in:

    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}");
    }
    

    De variabelen a, ben c worden doorgegeven aan de Multiply methode. De waarden van de variabelen worden afgedrukt tijdens de uitvoering van de methode en worden opnieuw afgedrukt nadat de methode is voltooid.

    Gehele getallen zijn waardetypen, die hun waarden laten kopiëren wanneer ze worden doorgegeven aan methoden. Wat denk je dat de uitvoer van c zal zijn?

  3. Sla uw code op en voer deze uit om de volgende uitvoer te bekijken:

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

    U ziet dat de waarde c alleen binnen de Multiply methode wordt gewijzigd. Buiten de methode behoudt c zijn oorspronkelijke waarde.

Test door referentie doorgeven

  1. Verwijder de vorige code uit de Visual Studio Code Editor.

  2. Voer de volgende code in de Visual Studio Code-editor in:

    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;
        }
    }
    

    De code begint met array geïnitialiseerd om enkele gehele getalwaarden te bevatten. De waarden worden weergegeven met behulp van de PrintArray methode. De Clear methode wordt aangeroepen op de matrix en vervolgens wordt de matrix opnieuw afgedrukt.

    Matrices zijn referentietypen. Referentietypen slaan het adres van hun waarden op in het geheugen. Wat denk je dat de uitvoer zal zijn?

  3. Sla uw code op en voer deze uit om de volgende uitvoer te bekijken:

    1 2 3 4 5 
    0 0 0 0 0
    

    U ziet dat de matrix buiten het bereik van de Clear methode blijft gewijzigd. Dit gebeurt omdat de Clear methode de waarden heeft bijgewerkt die zijn opgeslagen op elk adres.

Testen met tekenreeksen

Eerder hebt u geleerd dat tekenreeksen een onveranderbaar type zijn. Hoewel een tekenreeks een verwijzingstype is, kan de waarde ervan niet meer worden gewijzigd nadat deze is toegewezen, in tegenstelling tot een tabel. Mogelijk heb je dit opgemerkt als je methoden zoals string.Replace of string.ToUpper gebruikt. In deze taak leert u hoe u een veelvoorkomende fout kunt corrigeren die is gevonden bij het werken met tekenreeksen.

  1. Verwijder in de Visual Studio Code-editor alle bestaande code uit de vorige oefeningen.

  2. Voer de volgende code in de Visual Studio Code-editor in:

    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. Sla uw code op en voer deze uit om de volgende uitvoer te bekijken:

    Start: Healthy
    Middle: Unhealthy
    End: Healthy
    

    Als de SetHealth methode de status niet heeft uitgevoerd, hebt u mogelijk aangenomen dat de methode niet correct is uitgevoerd. In plaats daarvan is een nieuwe tekenreeks met de waarde 'Ongezond' gemaakt en vervolgens verloren gegaan in het bereik van de methode.

    U kunt dit probleem oplossen door in plaats van SetHealth de globale statusvariabele te gebruiken.

  4. Werk uw code als volgt bij:

    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 deze code overschrijft u de globale status variabele met de nieuwe tekenreekswaarde.

  5. Sla uw code op en voer deze uit om de volgende uitvoer te bekijken:

    Start: Healthy
    Middle: Unhealthy
    End: Unhealthy
    

    Nu wordt de bijgewerkte tekenreeks vastgelegd en correct opgeslagen.

Samenvatting

Dit is wat u tot nu toe hebt geleerd over waardetype- en referentietypeparameters:

  • Variabelen kunnen worden gecategoriseerd als waardetypen en verwijzingstypen.
  • Waardetypen bevatten rechtstreeks waarden en verwijzingstypen slaan het adres van de waarde op.
  • Methoden die waardetypeargumenten gebruiken, maken hun eigen kopie van de waarden.
  • Methoden die wijzigingen uitvoeren op een matrixparameter zijn van invloed op de oorspronkelijke invoermatrix.
  • String is een onveranderbaar referentietype.
  • Methoden die wijzigingen uitvoeren op een tekenreeksparameter, hebben geen invloed op de oorspronkelijke tekenreeks.