Oefening: een exceptie creëren en werpen
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.
Open een nieuw exemplaar van Visual Studio Code.
In het menu Bestand, selecteer Map openen.
Navigeer in het dialoogvenster Map Openen naar de map Bureaublad.
Selecteer Nieuwe map in het dialoogvenster Open Map.
Geef de nieuwe map ThrowExceptions101 een naam en selecteer vervolgens Map selecteren.
Selecteer Nieuwe terminal in het menu Terminal.
U gebruikt een .NET CLI-opdracht om een nieuwe console-app te maken.
Voer bij de opdrachtprompt van het TERMINAL-deelvenster de volgende opdracht in:
dotnet new consoleSluit het TERMINAL-deelvenster.
Een voorbeeldtoepassing controleren
Gebruik de volgende stappen om een voorbeeldtoepassing te laden en te controleren.
Open het bestand Program.cs.
Selecteer Opdrachtpalet in het menu Beeld.
Voer bij de opdrachtprompt .net in: g en selecteer vervolgens .NET: Assets genereren voor build en foutopsporing.
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; }Neem even de tijd om de code te controleren.
U ziet dat de toepassing de volgende taken uitvoert:
In de topniveaustatements worden
Console.ReadLine()statements gebruikt om waarden voorlowerBoundenupperBoundte verkrijgen.De topniveau-instructies geven
lowerBoundenupperBoundals argumenten bij het aanroepen van deAverageOfEvenNumbers-methode door.De
AverageOfEvenNumbersmethode voert de volgende taken uit:- Declareert lokale variabelen die worden gebruikt in berekeningen.
- Gebruikt een
forlus om de even getallen tussenlowerBoundenupperBoundte sommen. De som wordt opgeslagen insum. - Telt hoeveel getallen zijn opgenomen in de som. Het aantal wordt opgeslagen in
count. - Slaat het gemiddelde op van de opgetelde getallen in een variabele met de naam
average. De waarde vanaveragewordt geretourneerd.
Met de instructies op het hoogste niveau wordt de naar de console afgedrukte waarde door
AverageOfEvenNumbersgeretourneerd 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.
Gebruik de EXPLORER-weergave om het bestand launch.json te openen.
Werk in het launch.json-bestand het
consolekenmerk als volgt bij:// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console "console":"integratedTerminal",De standaardwaarde voor het
consolekenmerk isinternalConsole, die wordt uitgelijnd op het paneel DEBUG CONSOLE. Helaas biedt het paneel DEBUG CONSOLE geen ondersteuning voor console-invoer. DeintegratedTerminalinstelling wordt uitgelijnd op het TERMINAL-deelvenster, dat ondersteuning biedt voor consoleinvoer en -uitvoer.Sla de wijzigingen op in het launch.json-bestand en sluit het bestand.
Selecteer in het menu Uitvoeren van Visual Studio Code start de foutopsporing.
Schakel over naar het TERMINAL-deelvenster.
Voer bij de prompt 'ondergrens' 3 in
Voer bij de prompt 'bovengrens' 11 in
U ziet dat de toepassing het volgende bericht weergeeft en vervolgens onderbreekt:
The average of even numbers between 3 and 11 is 7.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.
Neem even de tijd om na te gaan hoe u het probleem wilt oplossen.
Een optie is het verpakken van de berekening in
averageeentrycodeblok encatchdeDivideByZerouitzondering 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
lowerBounddeze groter is dan of gelijk is aanupperBound, 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.
Bedenk welk uitzonderingstype moet worden gegooid.
Er zijn twee uitzonderingstypen die overeenkomen met het probleem:
-
ArgumentOutOfRangeException- Er mag alleen eenArgumentOutOfRangeExceptionuitzonderingstype worden gegenereerd wanneer de waarde van een argument zich buiten het toegestane bereik van waarden bevindt, zoals gedefinieerd door de aangeroepen methode. HoewelAverageOfEvenNumberser niet expliciet een toegestaan bereik wordt gedefinieerd voorlowerBoundofupperBound, impliceert de waarde vanlowerBoundhet toegestane bereik voorupperBound. -
InvalidOperationException: Er mag alleen eenInvalidOperationExceptionuitzonderingstype 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
ArgumentOutOfRangeExceptionuitzonderingstype is gericht op de argumenten die aan de methode worden doorgegeven. HetInvalidOperationExceptionuitzonderingstype is gericht op de operationele voorwaarden van de methode. In dit geval is hetArgumentOutOfRangeExceptionuitzonderingstype beperkter dan hetInvalidOperationExceptionuitzonderingstype.De
AverageOfEvenNumbersmethode moet eenArgumentOutOfRangeExceptionuitzondering genereren.-
Werk uw code boven aan de
AverageOfEvenNumbersmethode als volgt bij om het probleem met de bovengrens te detecteren:if (lowerBound >= upperBound) { } int sum = 0;Als u een
ArgumentOutOfRangeExceptionuitzondering wilt maken en genereren, werkt u hetifcodeblok 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
ArgumentOutOfRangeExceptionklasse 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).
Scrol omhoog naar de topniveauverklaringen.
Om de
AverageOfEvenNumbersmethodeaanroep en deConsole.WriteLineinstructie in eentrycodeblok 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}."); }Voer de volgende code in om de bijbehorende
catchcomponent te maken:catch(ArgumentOutOfRangeException ex) { }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
AverageOfEvenNumbersbellen met de nieuweupperBound. - Ga door naar
catchde uitzondering als de nieuweupperBoundopgegeven waarde nog steeds kleiner is dan of gelijk is aanlowerBound.
Om met
catchde uitzondering door te gaan, is een lus vereist. Omdat u deAverageOfEvenNumbersmethode ten minste één keer wilt aanroepen, moet er eendolus worden gebruikt.Als u de
tryencatchblokken in eendolus 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
whileexpressie is vereist om de afsluitvoorwaarde van eendolus te definiëren. Het is moeilijk om de voorwaarde op te geven voordat de inhoud van hetdocodeblok wordt gedefinieerd. Als u hetcatchcodeblok voltooit, kunt u dewhilebenodigde expressie definiëren.Als u het probleem aan de gebruiker wilt uitleggen en een nieuw
upperBoundwilt verkrijgen, werkt u hetcatchcodeblok 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
catchcodeblok 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?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
catchcodeblok 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
catchcodeblok bevat twee paden, een exit-pad en een nieuw bovengrenspad.Neem even de tijd om rekening te houden met de
whileexpressie die is vereist voor dedolus.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
whileexpressie die een Booleaanse waarde evalueert, kan worden gebruikt. Voorbeeld:while (exit == false);Met de voorgestelde
whileexpressie wordt het volgende gedrag vastgesteld:- de
dolus blijft herhalen zolang de Booleaanseexitwaarde gelijk is aanfalse. - de
dolus stopt met herhalen zodra de Booleaanse waardeexitgelijk is aantrue.
- de
Als u een Booleaanse variabele wilt instantiëren met de naam
exiten deze wilt gebruikenexitom de afsluitvoorwaarde van dedolus 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);Sla de bijgewerkte code op.
Selecteer in het menu Uitvoeren de foutopsporing starten.
Schakel over naar het TERMINAL-deelvenster.
Voer bij de prompt 'ondergrens' 3 in
Voer bij de prompt 'bovengrens' 3 in
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):Voer bij de prompt voor een nieuwe bovengrens 11 in
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.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.