Exerciții - Crearea și aruncarea unei excepții
Dezvoltatorii trebuie adesea să creeze și să genereze excepții dintr-o metodă, apoi să prindă aceste excepții mai jos în stiva de apeluri, unde pot fi tratate. Gestionarea excepțiilor vă ajută să asigurați stabilitatea aplicațiilor.
În acest exercițiu, veți începe cu o aplicație eșantion care include o condiție de eroare potențială în interiorul unei metode denumite. Metoda actualizată va face throw excepție atunci când detectează problema. Excepția va fi gestionată într-un catch bloc al codului care apelează metoda. Rezultatul este o aplicație care oferă o experiență de utilizator mai bună.
Creați un proiect de cod nou
Primul pas este să creați un proiect de cod pe care îl puteți utiliza în timpul acestui modul.
Deschideți o nouă instanță a Visual Studio Code.
În meniul Fișier , selectați Deschidere folder.
În caseta de dialog Deschidere folder , navigați la folderul Desktop Windows.
În caseta de dialog Deschidere folder , selectați Folder nou.
Denumiți noul folder ThrowExceptions101, apoi selectați Selectare folder.
În meniul terminal, selectați Terminal nou .
Veți utiliza o comandă .NET CLI pentru a crea o nouă aplicație consolă.
În linia de comandă din panoul TERMINAL, introduceți următoarea comandă:
dotnet new consoleÎnchideți panoul TERMINAL.
Revizuirea unei aplicații eșantion
Utilizați pașii următori pentru a încărca și a revizui o aplicație eșantion.
Deschideți fișierul Program.cs.
În meniul Vizualizare, selectați Paletă de comenzi.
În linia de comandă, introduceți .net: g , apoi selectați .NET: Generare active pentru compilare și depanare.
Înlocuiți conținutul fișierului Program.cs cu următorul cod:
// 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; }Luați un minut pentru a revizui codul.
Observați că aplicația efectuează următoarele activități:
Instrucțiunile de nivel superior utilizează
Console.ReadLine()instrucțiuni pentru a obține valori pentrulowerBoundșiupperBound.Instrucțiunile de nivel superior trec
lowerBoundșiupperBoundca argumente atunci când apelațiAverageOfEvenNumbersmetoda.Metoda
AverageOfEvenNumbersefectuează următoarele activități:- Declară variabile locale utilizate în calcule.
- Utilizează o
forbuclă pentru a aduna numerele par întrelowerBoundșiupperBound. Suma este stocată însum. - Contorizează numărul de numere incluse în sumă. Contorul este stocat în
count. - Stochează media numerelor însumate într-o variabilă denumită
average. Este returnată valoareaaverage.
Instrucțiunile de nivel superior imprimă valoarea returnată de
AverageOfEvenNumbersconsolă, apoi întrerupe execuția.
Configurarea mediului de depanare
Aplicația eșantion citește intrările utilizatorului de pe consolă. Panoul CONSOLĂ DEBUG nu acceptă citirea intrărilor de pe consolă. Trebuie să actualizați fișierul launch.json înainte de a rula această aplicație în depanator.
Utilizați vizualizarea EXPLORER pentru a deschide fișierul launch.json.
În fișierul launch.json, actualizați atributul
consoledupă cum urmează:// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console "console":"integratedTerminal",Valoarea implicită pentru
consoleatribut esteinternalConsole, care se aliniază la panoul CONSOLĂ DEBUG. Din păcate, panoul CONSOLĂ DEBUG nu acceptă intrările consolei.integratedTerminalSetarea se aliniază la panoul TERMINAL, care acceptă intrarea și ieșirea consolei.Salvați modificările în fișierul launch.json, apoi închideți fișierul.
În meniul Rulare cod Visual Studio, selectați Pornire depanare.
Comutați la panoul TERMINAL.
În solicitarea "limită inferioară", introduceți 3
În solicitarea "limită superioară", introduceți 11
Observați că aplicația afișează următorul mesaj, apoi se întrerupe:
The average of even numbers between 3 and 11 is 7.Pentru a ieși din aplicație, apăsați pe Enter.
Generați o excepție în metoda AverageOfEvenNumbers
Metoda AverageOfEvenNumbers așteaptă o limită superioară mai mare decât limita inferioară. Apare o DivideByZero eroare dacă limita inferioară este mai mare sau egală cu limita superioară.
Trebuie să actualizați AverageOfEvenNumbers metoda pentru a genera o excepție atunci când limita inferioară este mai mare sau egală cu limita superioară.
Luați un minut pentru a lua în considerare modul în care doriți să rezolvați problema.
O opțiune este să încadrați calculul în interiorul unui
averagebloc detrycod șicatchexcepțiaDivideByZeroatunci când are loc. Puteți să reintroduceți excepția și apoi să o gestionați în codul de apelare.O altă opțiune este să evaluați parametrii de intrare înainte de a începe calculele. Dacă
lowerBoundeste mai mare sau egal cuupperBound, puteți genera o excepție.Evaluarea parametrilor și aruncarea unei excepții înainte de a începe calculele este alegerea mai bună.
Luați în considerare tipul de excepție de aruncat.
Există două tipuri de excepții care se aliniază cu problema:
-
ArgumentOutOfRangeExceptionArgumentOutOfRangeException- Ar trebui lansat un tip de excepție doar atunci când valoarea unui argument se află în afara intervalului permis de valori, așa cum este definit de metoda invocată. DeșiAverageOfEvenNumbersnu definește explicit o zonă permisă pentrulowerBoundsauupperBound, valoarealowerBoundimplică intervalul permis pentruupperBound. -
InvalidOperationException: ArInvalidOperationExceptiontrebui lansat un tip de excepție doar atunci când condițiile de funcționare ale unei metode nu acceptă finalizarea cu succes a unui anumit apel de metodă. În acest caz, condițiile de funcționare sunt stabilite de parametrii de intrare ai metodei.
Atunci când aveți două sau mai multe tipuri de excepții din care să alegeți, selectați tipul de excepție care se potrivește mai îndeaproape problemei. În acest caz, cele două tipuri de excepții sunt aliniate în mod egal la problemă.
Atunci când aveți două sau mai multe tipuri de excepții aliniate la problemă în mod egal, selectați tipul de excepție cel mai restrâns. Tipul
ArgumentOutOfRangeExceptionde excepție este definit în funcție de argumentele transmise metodei. TipulInvalidOperationExceptionde excepție este definit în condițiile de funcționare ale metodei. În acest caz,ArgumentOutOfRangeExceptiontipul de excepție este mai restrâns decât tipul deInvalidOperationExceptionexcepție.Metoda
AverageOfEvenNumbersar trebui să genereze oArgumentOutOfRangeExceptionexcepție.-
În partea de sus a metodei
AverageOfEvenNumbers, pentru a detecta problema legată superioară, actualizați codul după cum urmează:if (lowerBound >= upperBound) { } int sum = 0;Pentru a crea și a genera o
ArgumentOutOfRangeExceptionexcepție, actualizați blocul deifcod după cum urmează:if (lowerBound >= upperBound) { throw new ArgumentOutOfRangeException("upperBound", "ArgumentOutOfRangeException: upper bound must be greater than lower bound."); }Această linie de cod inițializează o nouă instanță a
ArgumentOutOfRangeExceptionclasei cu numele parametrului de intrare care provoacă excepția și un mesaj de eroare specificat.
Prindeți excepția din codul de apelare
Ori de câte ori este posibil, excepțiile ar trebui să fie prinse la nivelul stivei de apeluri, unde pot fi tratate. În această aplicație eșantion, parametrii metodei AverageOfEvenNumbers pot fi gestionați în metoda de apelare (instrucțiunile de nivel superior).
Defilați în sus la instrucțiunile de nivel superior.
Pentru a încadra apelul de
AverageOfEvenNumbersmetodă șiConsole.WriteLineinstrucțiunea într-untrybloc de cod, actualizați codul după cum urmează: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}."); }Pentru a crea clauza asociată
catch, introduceți următorul cod:catch(ArgumentOutOfRangeException ex) { }Luați un minut pentru a lua în considerare modul în care puteți gestiona excepția.
Pentru a gestiona această excepție, codul trebuie să facă următoarele:
- Explicați problema utilizatorului.
- Obțineți o valoare nouă pentru
upperBound. - Apelați
AverageOfEvenNumbersutilizând noulupperBound. - Continuați cu
catchexcepția dacă noulupperBoundfurnizat este încă mai mic sau egal culowerBound.
catchContinuarea excepției necesită o buclă. Pentru că doriți să apelațiAverageOfEvenNumbersmetoda cel puțin o dată, trebuie utilizată odobuclă.Pentru a încadra și
tryacatchbloca în interiorul uneidobucle, actualizați codul după cum urmează: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) { } }Este
whilenecesară o expresie pentru a defini condiția de ieșire a uneidobucle. Este dificil să specificați condiția înainte de definirea conținutului bloculuidode cod. Finalizarea blocului decatchcod vă va ajuta să definiți expresiawhilenecesară.Pentru a explica problema utilizatorului și a obține o nouă
upperBound, actualizațicatchblocul de cod după cum urmează: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()); }Blocul de cod actualizat
catchdescrie problema și necesită ca utilizatorul să introducă o nouă limită superioară. Cu toate acestea, ce se întâmplă dacă utilizatorul nu are o valoare limită superioară validă de introdus? Ce se întâmplă dacă utilizatorul trebuie să iasă din buclă în loc să introducă o valoare?Pentru a-i oferi utilizatorului o opțiune de a ieși din buclă, nu de a introduce o nouă limită superioară, actualizați
catchblocul de cod după cum urmează: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); } }Blocul de cod actualizat
catchinclude două căi, o cale "ieșire" și o cale "nouă legată superioară".Luați un minut pentru a lua în considerare expresia
whilenecesară pentrudobuclă.Dacă utilizatorul introduce "Ieșire" la solicitare, codul ar trebui să iasă din buclă. Dacă utilizatorul introduce o nouă limită superioară, bucla ar trebui să continue. Se
whilepoate utiliza o expresie care evaluează o valoare booleană. De exemplu:while (exit == false);Expresia propusă
whileva stabili următorul comportament:- bucla
dova continua să se itereze atât timp cât Booleanexiteste egal cufalse. - bucla
dova opri iterarea de îndată ce Booleanexiteste egal cutrue.
- bucla
Pentru a instanția o variabilă booleană denumită
exitși pentruexita seta condiția de ieșire adobuclei, actualizați codul după cum urmează: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);Salvați codul actualizat.
În meniul Executare , selectați Pornire depanare.
Comutați la panoul TERMINAL.
În solicitarea "limită inferioară", introduceți 3
În solicitarea "limită superioară", introduceți 3
Observați că următoarea ieșire este afișată în panoul TERMINAL:
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):La solicitarea pentru o nouă limită superioară, introduceți 11
Observați că următoarea ieșire este afișată în panoul TERMINAL:
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.Pentru a ieși din aplicație, apăsați pe Enter.
Felicitări! Ați lansat, ați prins și ați tratat cu succes o excepție.
Recapitulare
Iată câteva lucruri importante de reținut din această unitate:
- Asigurați-vă că mediul de depanare este configurat pentru a accepta cerințele aplicației.
- Codul de metodă ar trebui să genereze o excepție atunci când este detectată o problemă sau o condiție.
- Excepțiile ar trebui să fie capturate la un nivel din stiva de apeluri, unde pot fi rezolvate.