Øvelse – opret og kast en undtagelse

Fuldført

Udviklere skal ofte oprette og smide undtagelser fra en metode og derefter fange disse undtagelser længere nede i opkaldsstakken, hvor de kan håndteres. Håndtering af undtagelser hjælper dig med at sikre stabiliteten af dine programmer.

I denne øvelse skal du starte med et eksempelprogram, der indeholder en potentiel fejlbetingelse i en kaldet metode. Din opdaterede metode vil throw være en undtagelse, når problemet registreres. Undtagelsen håndteres i en catch blok af den kode, der kalder metoden. Resultatet er et program, der giver en bedre brugeroplevelse.

Opret et nyt kodeprojekt

Det første trin er at oprette et kodeprojekt, som du kan bruge under dette modul.

  1. Åbn en ny forekomst af Visual Studio Code.

  2. Vælg Åbn mappe i menuen Filer.

  3. Gå til mappen Windows Desktop i dialogboksen Åbn mappe.

  4. Vælg Ny mappe i dialogboksen Åbn mappe.

  5. Navngiv den nye mappe ThrowExceptions101, og vælg derefter Vælg mappe.

  6. I menuen Terminal skal du vælge Ny terminal.

    Du skal bruge en .NET CLI-kommando til at oprette en ny konsolapp.

  7. Angiv følgende kommando ved kommandoprompten i TERMINAL-panelet:

    dotnet new console
    
  8. Luk terminalpanelet.

Gennemse et eksempelprogram

Brug følgende trin til at indlæse og gennemse et eksempelprogram.

  1. Åbn filen Program.cs.

  2. Vælg Kommandopalet i menuen Vis.

  3. I kommandoprompten skal du angive .net: g og derefter vælge .NET: Generér aktiver til build og fejlfinding.

  4. Erstat indholdet af filen Program.cs med følgende kode:

    // 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. Brug et øjeblik på at gennemse koden.

    Bemærk, at programmet udfører følgende opgaver:

    1. Sætningerne på øverste niveau bruger Console.ReadLine() sætninger til at hente værdier for lowerBound og upperBound.

    2. Sætningerne på øverste niveau overføres lowerBound og upperBound som argumenter, når metoden AverageOfEvenNumbers kaldes.

    3. Metoden AverageOfEvenNumbers udfører følgende opgaver:

      1. Deklarerer lokale variabler, der bruges i beregninger.
      2. Bruger en for løkke til at opsummere lige tal mellem lowerBound og upperBound. Summen gemmes i sum.
      3. Tæller, hvor mange tal der er inkluderet i summen. Antallet gemmes i count.
      4. Gemmer gennemsnittet af de sammenlagte tal i en variabel med navnet average. Værdien af average returneres.
    4. Sætningerne på øverste niveau udskriver den værdi, der returneres af AverageOfEvenNumbers til konsollen, og afbryder derefter udførelsen midlertidigt.

Konfigurer fejlfindingsmiljøet

Eksempelprogrammet læser brugerinput fra konsollen. Panelet DEBUG CONSOLE understøtter ikke læseinput fra konsollen. Du skal opdatere launch.json-filen, før du kan køre programmet i fejlfindingsprogrammet.

  1. Brug stifindervisningen til at åbne launch.json-filen.

  2. Opdater attributten console på følgende måde i filen launch.json:

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

    Standardværdien for attributten console er internalConsole, som er i overensstemmelse med panelet DEBUG CONSOLE. Desværre understøtter DEBUG CONSOLE-panelet ikke konsolinput. Indstillingen integratedTerminal justeres i forhold til TERMINAL-panelet, som understøtter konsolinput og -output.

  3. Gem ændringerne i launch.json-filen, og luk derefter filen.

  4. Vælg Start fejlfinding i menuen Kørsel af Visual Studio Code.

  5. Skift til terminalpanelet.

  6. Ved prompten "nedre grænse" skal du skrive 3

  7. Ved prompten "øvre grænse" skal du skrive 11

  8. Bemærk, at programmet viser følgende meddelelse og derefter stopper midlertidigt:

    The average of even numbers between 3 and 11 is 7.
    
  9. Tryk på Enter for at afslutte programmet.

Kast en undtagelse i metoden AverageOfEvenNumbers

Metoden AverageOfEvenNumbers forventer en øvre grænse, der er større end den nedre grænse. Der DivideByZero opstår en fejl, hvis den nedre grænse er større end eller lig med den øvre grænse.

Du skal opdatere AverageOfEvenNumbers metoden for at udløse en undtagelse, når den nedre grænse er større end eller lig med den øvre grænse.

  1. Brug et øjeblik på at overveje, hvordan du vil løse problemet.

    En mulighed er at ombryde beregningen af average i en try kodeblok og catch undtagelsen DivideByZero , når den opstår. Du kan omstyrte undtagelsen og derefter håndtere den i opkaldskoden.

    En anden mulighed er at evaluere inputparametrene, før du starter beregningerne. Hvis lowerBound er større end eller lig med upperBound, kan du udløse en undtagelse.

    Evaluering af parametrene og aktivering af en undtagelse, før beregningerne startes, er det bedste valg.

  2. Overvej, hvilken undtagelsestype der skal udløses.

    Der er to undtagelsestyper, der er i overensstemmelse med problemet:

    • ArgumentOutOfRangeException – En ArgumentOutOfRangeException undtagelsestype skal kun udløses, når værdien af et argument er uden for det tilladte interval af værdier, som defineret af den aktiverede metode. Selvom AverageOfEvenNumbers ikke eksplicit definerer et tilladt interval for lowerBound eller upperBound, betyder værdien af lowerBound det tilladte interval for upperBound.
    • InvalidOperationException: En InvalidOperationException undtagelsestype skal kun udløses, når driftsbetingelserne for en metode ikke understøtter en vellykket fuldførelse af et bestemt metodekald. I dette tilfælde er driftsbetingelserne fastlagt af inputparametrene for metoden.

    Når du har to eller flere undtagelsestyper at vælge imellem, skal du vælge den undtagelsestype, der passer bedre til problemet. I dette tilfælde er de to undtagelsestyper justeret ligeligt i forhold til problemet.

    Når du har to eller flere undtagelsestyper, der er justeret ligeligt efter problemet, skal du vælge den mest begrænsede undtagelsestype. Undtagelsestypen ArgumentOutOfRangeException er begrænset til de argumenter, der overføres til metoden. InvalidOperationException Undtagelsestypen er begrænset til driftsbetingelserne for metoden. I dette tilfælde er undtagelsestypen ArgumentOutOfRangeException mere begrænset end InvalidOperationException undtagelsestypen.

    Metoden AverageOfEvenNumbers skal udløse en ArgumentOutOfRangeException undtagelse.

  3. Øverst i AverageOfEvenNumbers metoden skal du opdatere din kode på følgende måde for at registrere problemet med den øvre grænse:

    if (lowerBound >= upperBound)
    {
    
    }
    
    int sum = 0;    
    
  4. Hvis du vil oprette og udløse en ArgumentOutOfRangeException undtagelse, skal du opdatere if kodeblokken på følgende måde:

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

    Denne kodelinje initialiserer en ny forekomst af ArgumentOutOfRangeException klassen med navnet på den inputparameter, der forårsager undtagelsen, og en angivet fejlmeddelelse.

Fange undtagelsen i opkaldskoden

Når det er muligt, skal undtagelser fanges på opkaldsstakniveauet, hvor de kan håndteres. I dette eksempelprogram kan parametrene for AverageOfEvenNumbers metoden administreres i kaldemetoden (sætningerne på øverste niveau).

  1. Rul op til sætningerne på øverste niveau.

  2. Hvis du vil omslutte metodekaldet og AverageOfEvenNumbers -sætningen Console.WriteLine i en try kodeblok, skal du opdatere din kode på følgende måde:

    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. Hvis du vil oprette den tilknyttede catch delsætning, skal du angive følgende kode:

    catch(ArgumentOutOfRangeException ex)
    {
    
    }
    
  4. Brug et øjeblik på at overveje, hvordan du kan håndtere undtagelsen.

    Hvis du vil håndtere denne undtagelse, skal koden gøre følgende:

    • Forklar problemet for brugeren.
    • Hent en ny værdi for upperBound.
    • Ring op AverageOfEvenNumbers ved hjælp af den nye upperBound.
    • Fortsæt til catch undtagelsen, hvis den nye upperBound angivne er stadig mindre end eller lig med lowerBound.

    Hvis du fortsætter med catch undtagelsen, kræver det en løkke. Da du vil kalde AverageOfEvenNumbers metoden mindst én gang, skal der bruges en do løkke.

  5. Hvis du vil omslutte blokkene try og catch i en do løkke, skal du opdatere din kode på følgende måde:

    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)
        {
    
        }
    }
    

    Der kræves et while udtryk for at definere afslutningsbetingelsen for en do løkke. Det er svært at angive betingelsen, før indholdet af do kodeblokken er defineret. Hvis du fuldfører catch kodeblokken, kan du definere det while udtryk, der skal bruges.

  6. Hvis du vil forklare problemet for brugeren og hente en ny upperBound, skal du opdatere kodeblokken catch på følgende måde:

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

    Den opdaterede catch kodeblok beskriver problemet og kræver, at brugeren angiver en ny øvre grænse. Men hvad nu, hvis brugeren ikke har en gyldig øvre grænseværdi at angive? Hvad sker der, hvis brugeren skal afslutte løkken i stedet for at angive en værdi?

  7. Hvis du vil give brugeren mulighed for at afslutte løkken i stedet for at angive en ny øvre grænse, skal du opdatere kodeblokken catch på følgende måde:

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

    Den opdaterede catch kodeblok indeholder to stier, en "exit"-sti og en "ny øvre grænse"-sti.

  8. Brug et øjeblik på at overveje det udtryk, while der kræves til løkken do .

    Hvis brugeren angiver "Afslut" ved prompten, skal koden afslutte løkken. Hvis brugeren angiver en ny øvre grænse, skal løkken fortsætte. Et while udtryk, der evaluerer en boolesk værdi, kan bruges. Eksempler:

    while (exit == false);
    

    Det foreslåede while udtryk etablerer følgende funktionsmåde:

    • løkken do fortsætter med at gentage, så længe den booleske exit værdi er lig med false.
    • løkken do stopper gentagelsen, så snart den booleske exit værdi er lig med true.
  9. Hvis du vil instantiere en boolesk variabel med navnet exitog bruge exit til at angive afslutningsbetingelsen for løkken do , skal du opdatere din kode på følgende måde:

    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. Gem din opdaterede kode.

  11. Vælg Start fejlfinding i menuen Kør.

  12. Skift til terminalpanelet.

  13. Ved prompten "nedre grænse" skal du skrive 3

  14. Ved prompten "øvre grænse" skal du skrive 3

  15. Bemærk, at følgende output vises i TERMINAL-panelet:

    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. Angiv 11 ved prompten om en ny øvre grænse

  17. Bemærk, at følgende output vises i TERMINAL-panelet:

    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. Tryk på Enter for at afslutte programmet.

Tillykke! Du har udløst, fanget og håndteret en undtagelse.

Resumé

Her er et par vigtige ting, du skal huske fra dette undermodul:

  • Sørg for, at fejlfindingsmiljøet er konfigureret til at understøtte dine programkrav.
  • Metodekoden skal udløse en undtagelse, når der registreres et problem eller en betingelse.
  • Undtagelser skal fanges på et niveau i opkaldsstakken, hvor de kan løses.