Übung: Erstellen und Auslösen einer Ausnahme
Entwickler müssen häufig Ausnahmen innerhalb einer Methode erstellen und auslösen und diese Ausnahmen dann weiter unten im Aufrufstapel abfangen, wo sie behandelt werden können. Die Ausnahmebehandlung hilft Ihnen dabei, die Stabilität Ihrer Anwendungen zu gewährleisten.
In dieser Übung beginnen Sie mit einer Beispielanwendung, die eine potenzielle Fehlerbedingung in einer aufgerufenen Methode enthält. Ihre aktualisierte Methode löst (über throw) eine Ausnahme aus, wenn sie das Problem erkennt. Die Ausnahme wird in einem catch Block des Codes behandelt, der die Methode aufruft. Das Ergebnis ist eine Anwendung, die eine bessere Benutzererfahrung bietet.
Erstellen eines neuen Codeprojekts
Der erste Schritt besteht darin, ein Codeprojekt zu erstellen, das Sie während dieses Moduls verwenden können.
Öffnen Sie eine neue Instanz von Visual Studio Code.
Wählen Sie im Menü "Datei " die Option "Ordner öffnen" aus.
Navigieren Sie im Dialogfeld "Ordner öffnen " zu Ihrem Windows-Desktopordner .
Wählen Sie im Dialogfeld "Ordner öffnen " die Option "Neuer Ordner" aus.
Benennen Sie den neuen Ordner ThrowExceptions101, und wählen Sie dann " Ordner auswählen" aus.
Wählen Sie im Menü "Terminal " die Option "Neues Terminal" aus.
Sie verwenden einen .NET CLI-Befehl, um eine neue Konsolen-App zu erstellen.
Geben Sie an der Eingabeaufforderung des TERMINALpanels den folgenden Befehl ein:
dotnet new consoleSchließen Sie das Panel TERMINAL.
Überprüfen einer Beispielanwendung
Führen Sie die folgenden Schritte aus, um eine Beispielanwendung zu laden und zu überprüfen.
Öffnen Sie die Datei „Program.cs“.
Wählen Sie im Menü "Ansicht" die Befehlspalette aus.
Geben Sie an der Eingabeaufforderung .net: g ein, und wählen Sie dann .NET: Ressourcen für Build und Debug generieren.
Ersetzen Sie den Inhalt der Datei Program.cs durch den folgenden 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; }Überprüfen Sie kurz den Code.
Beachten Sie, dass die Anwendung die folgenden Aufgaben ausführt:
Die Anweisungen auf oberster Ebene verwenden
Console.ReadLine()Anweisungen zum Abrufen von Werten fürlowerBoundundupperBound.Die Anweisungen der obersten Ebene übergeben
lowerBoundundupperBoundals Argumente beim Aufrufen derAverageOfEvenNumbersMethode.Die
AverageOfEvenNumbersMethode führt die folgenden Aufgaben aus:- Deklariert lokale Variablen, die in Berechnungen verwendet werden.
- Verwendet eine
for-Schleife, um die geraden Zahlen zwischenlowerBoundundupperBoundzu summieren. Die Summe wird gespeichert insum. - Zählt, wie viele Zahlen in die Summe einbezogen werden. Die Anzahl wird in
countgespeichert. - Speichert den Mittelwert der summierten Zahlen in einer Variablen mit dem Namen
average. Der Wert vonaveragewird zurückgegeben.
Die Anweisungen der obersten Ebene drucken den Wert, der von
AverageOfEvenNumberszur Konsole zurückgegeben wird, und halten dann die Ausführung an.
Konfigurieren der Debugumgebung
Die Beispielanwendung liest Benutzereingaben aus der Konsole vor. Der DEBUG CONSOLE-Bereich unterstützt das Lesen von Eingaben über die Konsole nicht. Sie müssen die launch.json Datei aktualisieren, bevor Sie diese Anwendung im Debugger ausführen können.
Verwenden Sie die EXPLORER-Ansicht, um die Datei „launch.json“ zu öffnen.
Aktualisieren Sie in der Datei „launch.json“ das Attribut
consolewie folgt:// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console "console":"integratedTerminal",Der Standardwert für das
console-Attribut lautetinternalConsoleund ist damit auf das Panel DEBUGGING-KONSOLE ausgerichtet. Leider unterstützt der DEBUG CONSOLE-Bereich keine Konsoleneingaben. DieintegratedTerminal-Einstellung entspricht dem Panel „Terminal“, das Konsoleneingaben und -ausgaben unterstützt.Speichern Sie Ihre Änderungen in der launch.json Datei, und schließen Sie die Datei.
Wählen Sie im Menü " Visual Studio Code Ausführen" die Option "Debuggen starten" aus.
Wechseln Sie zum Bereich TERMINAL.
Geben Sie an der Eingabeaufforderung "Untergrenze" 3 ein.
Geben Sie an der Eingabeaufforderung "obere Grenze" 11 ein.
Beachten Sie, dass die Anwendung die folgende Meldung anzeigt und dann angehalten wird:
The average of even numbers between 3 and 11 is 7.Drücken Sie die EINGABETASTE, um die Anwendung zu beenden.
Auslösen einer Ausnahme in der AverageOfEvenNumbers-Methode
Die AverageOfEvenNumbers Methode erwartet eine obere Grenze, die größer als die untere Grenze ist. Wenn die untere Grenze größer oder gleich der oberen Grenze ist, tritt ein DivideByZero Fehler auf.
Sie müssen die AverageOfEvenNumbers Methode aktualisieren, um eine Ausnahme auszuwerfen, wenn die untere Grenze größer oder gleich der oberen Grenze ist.
Nehmen Sie sich eine Minute Zeit, um zu überlegen, wie Sie das Problem beheben möchten.
Eine Option besteht darin, die Berechnung von
averagemit einemtry-Codeblock zu umschließen und diecatch-Ausnahme bei ihrem Auftreten überDivideByZeroabzufangen. Sie können die Ausnahme erneut auslösen und anschließend im aufrufenden Code behandeln.Eine weitere Option besteht darin, die Eingabeparameter vor dem Starten der Berechnungen auszuwerten. Wenn
lowerBoundgrößer oder gleichupperBoundist, können Sie eine Ausnahme auslösen.Die Auswertung der Parameter und das Auslösen einer Ausnahme vor dem Starten der Berechnungen ist die bessere Wahl.
Überlegen Sie, welcher Ausnahmetyp ausgelöst werden soll.
Es gibt zwei Ausnahmetypen, die mit dem Problem übereinstimmen:
-
ArgumentOutOfRangeException- EinArgumentOutOfRangeExceptionAusnahmetyp sollte nur ausgelöst werden, wenn sich der Wert eines Arguments außerhalb des zulässigen Wertebereichs befindet, wie durch die aufgerufene Methode definiert. ObwohlAverageOfEvenNumbersein zulässiger Bereich nicht explizit fürlowerBoundoderupperBounddefiniert wird, impliziert der WertlowerBoundden zulässigen Bereich fürupperBound. -
InvalidOperationException: EinInvalidOperationExceptionAusnahmetyp sollte nur ausgelöst werden, wenn die Betriebsbedingungen einer Methode den erfolgreichen Abschluss eines bestimmten Methodenaufrufs nicht unterstützen. In diesem Fall werden die Betriebsbedingungen durch die Eingabeparameter der Methode festgelegt.
Wenn Sie zwei oder mehr Ausnahmetypen auswählen möchten, wählen Sie den Ausnahmetyp aus, der dem Problem näher entspricht. In diesem Fall sind die beiden Ausnahmetypen im gleichen Maße auf das Problem abgestimmt.
Wenn Sie zwei oder mehr Ausnahmetypen haben, die auf das Problem gleichermaßen ausgerichtet sind, wählen Sie den am engsten begrenzten Ausnahmetyp aus. Der
ArgumentOutOfRangeExceptionAusnahmetyp ist auf die Argumente zugeschnitten, die an die Methode übergeben werden. DerInvalidOperationExceptionAusnahmetyp ist auf die Betriebsbedingungen der Methode abgegrenzt. In diesem Fall ist derArgumentOutOfRangeExceptionAusnahmetyp enger gefasst als derInvalidOperationExceptionAusnahmetyp.Die
AverageOfEvenNumbersMethode sollte eineArgumentOutOfRangeExceptionAusnahme auslösen.-
Aktualisieren Sie den Code am Anfang der
AverageOfEvenNumbers-Methode wie folgt, um das Problem der oberen Grenze zu erkennen:if (lowerBound >= upperBound) { } int sum = 0;Um eine
ArgumentOutOfRangeExceptionAusnahme zu erstellen und auszuwerfen, aktualisieren Sie denifCodeblock wie folgt:if (lowerBound >= upperBound) { throw new ArgumentOutOfRangeException("upperBound", "ArgumentOutOfRangeException: upper bound must be greater than lower bound."); }Diese Codezeile initialisiert eine neue Instanz der
ArgumentOutOfRangeExceptionKlasse mit dem Namen des Eingabeparameters, der die Ausnahme und eine angegebene Fehlermeldung verursacht.
Abfangen der Ausnahme im aufrufenden Code
Ausnahmen sollten nach Möglichkeit auf einer Ebene innerhalb der Aufrufliste abgefangen werden, auf der sie behandelt werden können. In dieser Beispielanwendung können die Parameter der AverageOfEvenNumbers Methode in der aufrufenden Methode (die Anweisungen der obersten Ebene) verwaltet werden.
Scrollen Sie nach oben zu den Anweisungen der obersten Ebene.
Um den
AverageOfEvenNumbersMethodenaufruf und dieConsole.WriteLineAnweisung in einentryCodeblock einzuschließen, aktualisieren Sie Ihren Code wie folgt: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}."); }Geben Sie den folgenden Code ein, um die zugeordnete
catchKlausel zu erstellen:catch(ArgumentOutOfRangeException ex) { }Nehmen Sie sich eine Minute Zeit, um zu überlegen, wie Sie die Ausnahme behandeln können.
Um diese Ausnahme zu behandeln, muss Ihr Code die folgenden Schritte ausführen:
- Erläutern Sie das Problem für den Benutzer.
- Abrufen eines neuen Werts für
upperBound. - Aufrufen von
AverageOfEvenNumbersmit dem neuenupperBound-Wert. - Erneutes Abfangen der Ausnahme (über
catch), wenn der neu bereitgestellteupperBound-Wert immer noch kleiner oder gleichlowerBoundist.
Das fortgesetzte Abfangen der Ausnahme (über
catch) erfordert eine Schleife. Da Sie dieAverageOfEvenNumbersMethode mindestens einmal aufrufen möchten, sollte einedoSchleife verwendet werden.Um die Blöcke
tryundcatchin einedoSchleife einzuschließen, aktualisieren Sie Ihren Code wie folgt: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) { } }Ein
whileAusdruck ist erforderlich, um die Beendigungsbedingung einerdoSchleife zu definieren. Es ist schwierig, die Bedingung anzugeben, bevor der Inhalt desdoCodeblocks definiert wird. Wenn Sie dencatchCodeblock abschließen, können Sie denwhilebenötigten Ausdruck definieren.Um das Problem für den Benutzer zu erläutern und einen neuen
upperBoundzu erhalten, aktualisieren Sie dencatchCodeblock wie folgt: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()); }Der aktualisierte
catchCodeblock beschreibt das Problem und erfordert, dass der Benutzer eine neue obere Grenze eingibt. Was geschieht jedoch, wenn der Benutzer keinen gültigen oberen Grenzwert eingeben kann? Was geschieht, wenn der Benutzer die Schleife beenden muss, anstatt einen Wert einzugeben?Um dem Benutzer eine Option zum Beenden der Schleife zu ermöglichen, anstatt eine neue obere Grenze einzugeben, aktualisieren Sie den
catchCodeblock wie folgt: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); } }Der aktualisierte Codeblock
catchenthält zwei Pfade, einen Pfad für die Beendigung und einen Pfad für eine neue Obergrenze.Nehmen Sie sich einen Moment Zeit, um den für die
while-Schleife benötigtendo-Ausdruck zu betrachten.Wenn der Benutzer an der Eingabeaufforderung "Exit" eingibt, sollte der Code die Schleife beenden. Wenn der Benutzer eine neue obere Grenze eingibt, sollte die Schleife fortgesetzt werden. Ein
whileAusdruck, der einen booleschen Ausdruck auswertet, kann verwendet werden. Beispiel:while (exit == false);Der vorgeschlagene
whileAusdruck legt das folgende Verhalten fest:- Die
do-Schleife wird so lange durchlaufen, bis der boolesche Wertexitalsfalseausgewertet wird. - die
doSchleife beendet das Iterieren, sobald der boolescheexitWert gleichtrueist.
- Die
Um eine boolesche Variable namens
exitzu instanziieren undexitzur Festlegung der Beendigungsbedingung derdo-Schleife zu verwenden, aktualisieren Sie Ihren Code wie folgt: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);Speichern Sie den aktualisierten Code.
Wählen Sie im Menü "Ausführen " die Option "Debuggen starten" aus.
Wechseln Sie zum Bereich TERMINAL.
Geben Sie an der Eingabeaufforderung "Untergrenze" 3 ein.
Geben Sie an der Eingabeaufforderung "obere Grenze" 3 ein.
Beachten Sie, dass die folgende Ausgabe im TERMINAL-Bereich angezeigt wird:
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):Geben Sie an der Eingabeaufforderung für eine neue obere Grenze 11 ein.
Beachten Sie, dass die folgende Ausgabe im TERMINAL-Bereich angezeigt wird:
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.Drücken Sie die EINGABETASTE, um die Anwendung zu beenden.
Glückwunsch! Sie haben erfolgreich eine Ausnahme ausgelöst, abgefangen und behandelt.
Zusammenfassung
Nachstehend finden Sie nochmals die wichtigsten Punkte aus dieser Lerneinheit:
- Stellen Sie sicher, dass Ihre Debugumgebung für die Unterstützung Ihrer Anwendungsanforderungen konfiguriert ist.
- Der Methodencode sollte eine Ausnahme auslösen, wenn ein Problem oder eine Bedingung erkannt wird.
- Ausnahmen sollten auf einer Ebene im Aufrufstapel erfasst werden, in der sie aufgelöst werden können.