Oefening: een exceptie creëren en werpen

Voltooid

Ontwikkelaars moeten vaak uitzonderingen genereren en gooien vanuit een methode en vervolgens deze uitzonderingen verderop in de aanroepstack opvangen, waar ze kunnen worden afgehandeld. De afhandeling van uitzonderingen helpt u om de stabiliteit van uw toepassingen te garanderen.

In deze oefening begint u met een voorbeeldtoepassing die een mogelijke foutvoorwaarde in een aangeroepen methode bevat. De bijgewerkte methode zal throw een uitzondering werpen wanneer het probleem wordt gedetecteerd. De uitzondering wordt verwerkt in een catch blok van de code die de methode aanroept. Het resultaat is een toepassing die een betere gebruikerservaring biedt.

Een nieuw codeproject maken

De eerste stap is het maken van een codeproject dat u tijdens deze module kunt gebruiken.

  1. Open een nieuw exemplaar van Visual Studio Code.

  2. In het menu Bestand, selecteer Map openen.

  3. Navigeer in het dialoogvenster Map Openen naar de map Bureaublad.

  4. Selecteer Nieuwe map in het dialoogvenster Open Map.

  5. Geef de nieuwe map ThrowExceptions101 een naam en selecteer vervolgens Map selecteren.

  6. Selecteer Nieuwe terminal in het menu Terminal.

    U gebruikt een .NET CLI-opdracht om een nieuwe console-app te maken.

  7. Voer bij de opdrachtprompt van het TERMINAL-deelvenster de volgende opdracht in:

    dotnet new console
    
  8. Sluit het TERMINAL-deelvenster.

Een voorbeeldtoepassing controleren

Gebruik de volgende stappen om een voorbeeldtoepassing te laden en te controleren.

  1. Open het bestand Program.cs.

  2. Selecteer Opdrachtpalet in het menu Beeld.

  3. Voer bij de opdrachtprompt .net in: g en selecteer vervolgens .NET: Assets genereren voor build en foutopsporing.

  4. Vervang de inhoud van het bestand Program.cs door de volgende code:

    // Prompt the user for the lower and upper bounds
    Console.Write("Enter the lower bound: ");
    int lowerBound = int.Parse(Console.ReadLine());
    
    Console.Write("Enter the upper bound: ");
    int upperBound = int.Parse(Console.ReadLine());
    
    decimal averageValue = 0;
    
    // Calculate the sum of the even numbers between the bounds
    averageValue = AverageOfEvenNumbers(lowerBound, upperBound);
    
    // Display the value returned by AverageOfEvenNumbers in the console
    Console.WriteLine($"The average of even numbers between {lowerBound} and {upperBound} is {averageValue}.");
    
    // Wait for user input
    Console.ReadLine();
    
    static decimal AverageOfEvenNumbers(int lowerBound, int upperBound)
    {
        int sum = 0;
        int count = 0;
        decimal average = 0;
    
        for (int i = lowerBound; i <= upperBound; i++)
        {
            if (i % 2 == 0)
            {
                sum += i;
                count++;
            }
        }
    
        average = (decimal)sum / count;
    
        return average;
    }
    
  5. Neem even de tijd om de code te controleren.

    U ziet dat de toepassing de volgende taken uitvoert:

    1. In de topniveaustatements worden Console.ReadLine() statements gebruikt om waarden voor lowerBound en upperBound te verkrijgen.

    2. De topniveau-instructies geven lowerBound en upperBound als argumenten bij het aanroepen van de AverageOfEvenNumbers-methode door.

    3. De AverageOfEvenNumbers methode voert de volgende taken uit:

      1. Declareert lokale variabelen die worden gebruikt in berekeningen.
      2. Gebruikt een for lus om de even getallen tussen lowerBound en upperBound te sommen. De som wordt opgeslagen in sum.
      3. Telt hoeveel getallen zijn opgenomen in de som. Het aantal wordt opgeslagen in count.
      4. Slaat het gemiddelde op van de opgetelde getallen in een variabele met de naam average. De waarde van average wordt geretourneerd.
    4. Met de instructies op het hoogste niveau wordt de naar de console afgedrukte waarde door AverageOfEvenNumbers geretourneerd en vervolgens wordt de uitvoering gepauzeerd.

De foutopsporingsomgeving configureren

De voorbeeldtoepassing leest gebruikersinvoer uit de console. Het DEBUG CONSOLE-venster ondersteunt het lezen van invoer van de console niet. U moet het launch.json-bestand bijwerken voordat u deze toepassing kunt uitvoeren in het foutopsporingsprogramma.

  1. Gebruik de EXPLORER-weergave om het bestand launch.json te openen.

  2. Werk in het launch.json-bestand het console kenmerk als volgt bij:

    // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
    "console":"integratedTerminal",
    

    De standaardwaarde voor het console kenmerk is internalConsole, die wordt uitgelijnd op het paneel DEBUG CONSOLE. Helaas biedt het paneel DEBUG CONSOLE geen ondersteuning voor console-invoer. De integratedTerminal instelling wordt uitgelijnd op het TERMINAL-deelvenster, dat ondersteuning biedt voor consoleinvoer en -uitvoer.

  3. Sla de wijzigingen op in het launch.json-bestand en sluit het bestand.

  4. Selecteer in het menu Uitvoeren van Visual Studio Code start de foutopsporing.

  5. Schakel over naar het TERMINAL-deelvenster.

  6. Voer bij de prompt 'ondergrens' 3 in

  7. Voer bij de prompt 'bovengrens' 11 in

  8. U ziet dat de toepassing het volgende bericht weergeeft en vervolgens onderbreekt:

    The average of even numbers between 3 and 11 is 7.
    
  9. Druk op Enter om de toepassing af te sluiten.

Een uitzondering genereren in de methode AverageOfEvenNumbers

De AverageOfEvenNumbers methode verwacht een bovengrens die groter is dan de ondergrens. Er DivideByZero treedt een fout op als de ondergrens groter is dan of gelijk is aan de bovengrens.

U moet de AverageOfEvenNumbers methode bijwerken om een uitzondering te genereren wanneer de ondergrens groter is dan of gelijk is aan de bovengrens.

  1. Neem even de tijd om na te gaan hoe u het probleem wilt oplossen.

    Een optie is het verpakken van de berekening in average een try codeblok en catch de DivideByZero uitzondering wanneer dit gebeurt. U kunt de uitzondering opnieuw werpen en deze vervolgens afhandelen in de aanroepende code.

    Een andere optie is om de invoerparameters te evalueren voordat u de berekeningen start. Als lowerBound deze groter is dan of gelijk is aan upperBound, kunt u een uitzondering genereren.

    Het evalueren van de parameters en het genereren van een uitzondering voordat de berekeningen worden gestart, is de betere keuze.

  2. Bedenk welk uitzonderingstype moet worden gegooid.

    Er zijn twee uitzonderingstypen die overeenkomen met het probleem:

    • ArgumentOutOfRangeException - Er mag alleen een ArgumentOutOfRangeException uitzonderingstype worden gegenereerd wanneer de waarde van een argument zich buiten het toegestane bereik van waarden bevindt, zoals gedefinieerd door de aangeroepen methode. Hoewel AverageOfEvenNumbers er niet expliciet een toegestaan bereik wordt gedefinieerd voor lowerBound of upperBound, impliceert de waarde van lowerBound het toegestane bereik voor upperBound.
    • InvalidOperationException: Er mag alleen een InvalidOperationException uitzonderingstype worden gegenereerd wanneer de operationele voorwaarden van een methode geen ondersteuning bieden voor de geslaagde voltooiing van een bepaalde methodeaanroep. In dit geval worden de operationele voorwaarden vastgesteld door de invoerparameters van de methode.

    Wanneer u twee of meer uitzonderingstypen hebt waaruit u kunt kiezen, selecteert u het uitzonderingstype dat beter bij het probleem past. In dit geval worden de twee uitzonderingstypen evenzeer afgestemd op het probleem.

    Wanneer u twee of meer uitzonderingstypen hebt die op het probleem zijn afgestemd, selecteert u het meest beperkte uitzonderingstype. Het ArgumentOutOfRangeException uitzonderingstype is gericht op de argumenten die aan de methode worden doorgegeven. Het InvalidOperationException uitzonderingstype is gericht op de operationele voorwaarden van de methode. In dit geval is het ArgumentOutOfRangeException uitzonderingstype beperkter dan het InvalidOperationException uitzonderingstype.

    De AverageOfEvenNumbers methode moet een ArgumentOutOfRangeException uitzondering genereren.

  3. Werk uw code boven aan de AverageOfEvenNumbers methode als volgt bij om het probleem met de bovengrens te detecteren:

    if (lowerBound >= upperBound)
    {
    
    }
    
    int sum = 0;    
    
  4. Als u een ArgumentOutOfRangeException uitzondering wilt maken en genereren, werkt u het if codeblok als volgt bij:

    if (lowerBound >= upperBound)
    {
        throw new ArgumentOutOfRangeException("upperBound", "ArgumentOutOfRangeException: upper bound must be greater than lower bound.");
    }
    

    Met deze coderegel wordt een nieuw exemplaar van de ArgumentOutOfRangeException klasse geïnitialiseerd met de naam van de invoerparameter die de uitzondering en een opgegeven foutbericht veroorzaakt.

Zorg ervoor dat de uitzondering in de aanroepende code wordt opgevangen

Waar mogelijk moeten uitzonderingen worden afgevangen op het niveau van de aanroepstack, waar ze kunnen worden verwerkt. In deze voorbeeldtoepassing kunnen de parameters van de AverageOfEvenNumbers methode worden beheerd in de aanroepmethode (de instructies op het hoogste niveau).

  1. Scrol omhoog naar de topniveauverklaringen.

  2. Om de AverageOfEvenNumbers methodeaanroep en de Console.WriteLine instructie in een try codeblok te plaatsen, werkt u uw code als volgt bij:

    try
    {
        // Calculate the sum of the even numbers between the bounds
        averageValue = AverageOfEvenNumbers(lowerBound, upperBound);
    
        // Display the result to the user
        Console.WriteLine($"The average of even numbers between {lowerBound} and {upperBound} is {averageValue}.");
    }
    
  3. Voer de volgende code in om de bijbehorende catch component te maken:

    catch(ArgumentOutOfRangeException ex)
    {
    
    }
    
  4. Neem even de tijd om na te gaan hoe u de uitzondering kunt afhandelen.

    Als u deze uitzondering wilt afhandelen, moet uw code het volgende doen:

    • Leg het probleem uit aan de gebruiker.
    • Haal een nieuwe waarde op voor upperBound.
    • U kunt AverageOfEvenNumbers bellen met de nieuwe upperBound.
    • Ga door naar catch de uitzondering als de nieuwe upperBound opgegeven waarde nog steeds kleiner is dan of gelijk is aan lowerBound.

    Om met catch de uitzondering door te gaan, is een lus vereist. Omdat u de AverageOfEvenNumbers methode ten minste één keer wilt aanroepen, moet er een do lus worden gebruikt.

  5. Als u de try en catch blokken in een do lus wilt insluiten, werkt u uw code als volgt bij:

    do
    {
        try
        {
            // Calculate the sum of the even numbers between the bounds
            averageValue = AverageOfEvenNumbers(lowerBound, upperBound);
    
            // Display the result to the user
            Console.WriteLine($"The average of even numbers between {lowerBound} and {upperBound} is {averageValue}.");
        }
        catch (ArgumentOutOfRangeException ex)
        {
    
        }
    }
    

    Een while expressie is vereist om de afsluitvoorwaarde van een do lus te definiëren. Het is moeilijk om de voorwaarde op te geven voordat de inhoud van het do codeblok wordt gedefinieerd. Als u het catch codeblok voltooit, kunt u de while benodigde expressie definiëren.

  6. Als u het probleem aan de gebruiker wilt uitleggen en een nieuw upperBoundwilt verkrijgen, werkt u het catch codeblok als volgt bij:

    catch (ArgumentOutOfRangeException ex)
    {
        Console.WriteLine("An error has occurred.");
        Console.WriteLine(ex.Message);
        Console.WriteLine($"The upper bound must be greater than {lowerBound}");
        Console.Write($"Enter a new upper bound: ");
        upperBound = int.Parse(Console.ReadLine());
    }
    

    Het bijgewerkte catch codeblok beschrijft het probleem en vereist dat de gebruiker een nieuwe bovengrens invoert. Wat gebeurt er echter als de gebruiker geen geldige bovengrenswaarde heeft om in te voeren? Wat gebeurt er als de gebruiker de lus moet afsluiten in plaats van een waarde in te voeren?

  7. Als u de gebruiker een optie wilt bieden om de lus af te sluiten in plaats van een nieuwe bovengrens in te voeren, werkt u het catch codeblok als volgt bij:

    catch (ArgumentOutOfRangeException ex)
    {
        Console.WriteLine("An error has occurred.");
        Console.WriteLine(ex.Message);
        Console.WriteLine($"The upper bound must be greater than {lowerBound}");
        Console.Write($"Enter a new upper bound (or enter Exit to quit): ");
        string? userResponse = Console.ReadLine();
        if (userResponse.ToLower().Contains("exit"))
        {
    
        }
        else
        {
            upperBound = int.Parse(userResponse);
        }
    }
    

    Het bijgewerkte catch codeblok bevat twee paden, een exit-pad en een nieuw bovengrenspad.

  8. Neem even de tijd om rekening te houden met de while expressie die is vereist voor de do lus.

    Als de gebruiker 'Afsluiten' invoert bij de prompt, moet de code de lus afsluiten. Als de gebruiker een nieuwe bovengrens invoert, moet de lus doorgaan. Een while expressie die een Booleaanse waarde evalueert, kan worden gebruikt. Voorbeeld:

    while (exit == false);
    

    Met de voorgestelde while expressie wordt het volgende gedrag vastgesteld:

    • de do lus blijft herhalen zolang de Booleaanse exit waarde gelijk is aan false.
    • de do lus stopt met herhalen zodra de Booleaanse waarde exit gelijk is aan true.
  9. Als u een Booleaanse variabele wilt instantiëren met de naam exiten deze wilt gebruiken exit om de afsluitvoorwaarde van de do lus in te stellen, werkt u de code als volgt bij:

    bool exit = false;
    
    do
    {
        try
        {
            // Calculate the sum of the even numbers between the bounds
            averageValue = AverageOfEvenNumbers(lowerBound, upperBound);
    
            // Display the result to the user
            Console.WriteLine($"The average of even numbers between {lowerBound} and {upperBound} is {averageValue}.");
    
            exit = true;
        }
        catch (ArgumentOutOfRangeException ex)
        {
            Console.WriteLine("An error has occurred.");
            Console.WriteLine(ex.Message);
            Console.WriteLine($"The upper bound must be greater than {lowerBound}");
            Console.Write($"Enter a new upper bound (or enter Exit to quit): ");
            string? userResponse = Console.ReadLine();
            if (userResponse.ToLower().Contains("exit"))
            {
                exit = true;
            }
            else
            {
                exit = false;
                upperBound = int.Parse(userResponse);
            }
        }    
    } while (exit == false);
    
  10. Sla de bijgewerkte code op.

  11. Selecteer in het menu Uitvoeren de foutopsporing starten.

  12. Schakel over naar het TERMINAL-deelvenster.

  13. Voer bij de prompt 'ondergrens' 3 in

  14. Voer bij de prompt 'bovengrens' 3 in

  15. U ziet dat de volgende uitvoer wordt weergegeven in het terminal-deelvenster.

    Enter the lower bound: 3
    Enter the upper bound: 3
    An error has occurred.
    ArgumentOutOfRangeException: upper bound must be greater than lower bound. (Parameter 'upperBound')
    The upper bound must be greater than 3
    Enter a new upper bound (or enter Exit to quit):
    
  16. Voer bij de prompt voor een nieuwe bovengrens 11 in

  17. U ziet dat de volgende uitvoer wordt weergegeven in het terminal-deelvenster.

    Enter the lower bound: 3
    Enter the upper bound: 3
    An error has occurred.
    ArgumentOutOfRangeException: upper bound must be greater than lower bound. (Parameter 'upperBound')
    The upper bound must be greater than 3
    Enter a new upper bound (or enter Exit to quit): 11
    The average of even numbers between 3 and 11 is 7.
    
  18. Druk op Enter om de toepassing af te sluiten.

Gefeliciteerd! U hebt met succes een uitzondering opgeworpen, gevangen en afgehandeld.

Samenvatting

Hier volgen enkele belangrijke dingen die u in deze les moet onthouden:

  • Zorg ervoor dat uw foutopsporingsomgeving is geconfigureerd ter ondersteuning van uw toepassingsvereisten.
  • Methodecode moet een uitzondering genereren wanneer een probleem of voorwaarde wordt gedetecteerd.
  • Uitzonderingen moeten op een bepaald niveau in de aanroepstapel worden afgevangen waar ze kunnen worden opgelost.