แบบฝึกหัด - สร้างและโยนข้อยกเว้น

เสร็จสมบูรณ์เมื่อ

นักพัฒนามักจําเป็นต้องสร้างและโยนข้อยกเว้นจากภายในเมธอด จากนั้นจะตรวจจับข้อยกเว้นเหล่านั้นลงในสแตกการโทรที่สามารถจัดการได้ การจัดการข้อยกเว้นช่วยให้คุณมั่นใจถึงความเสถียรของแอปพลิเคชันของคุณ

ในแบบฝึกหัดนี้ คุณจะเริ่มต้นด้วยแอปพลิเคชันตัวอย่างที่มีเงื่อนไขข้อผิดพลาดที่อาจเกิดขึ้นภายในเมธอดที่เรียกว่า วิธีการอัปเดตของคุณจะ throw เกิดข้อยกเว้นเมื่อตรวจพบปัญหา ข้อยกเว้นจะได้รับการจัดการใน catch บล็อกของโค้ดที่เรียกใช้เมธอด ผลลัพธ์คือแอปพลิเคชันที่ให้ประสบการณ์ผู้ใช้ที่ดีขึ้น

สร้างโครงการรหัสใหม่

ขั้นตอนแรกคือการสร้างโครงการรหัสที่คุณสามารถใช้ในระหว่างโมดูลนี้

  1. เปิดอินสแตนซ์ใหม่ของ Visual Studio Code

  2. บนเมนู ไฟล์ เลือก เปิดโฟลเดอร์

  3. ในกล่องโต้ตอบ เปิดโฟลเดอร์ ให้นําทางไปยังโฟลเดอร์ Windows Desktop ของคุณ

  4. บนกล่องโต้ตอบ เปิดโฟลเดอร์ เลือก โฟลเดอร์ใหม่

  5. ตั้งชื่อโฟลเดอร์ใหม่ว่า ThrowExceptions101 จากนั้นเลือก เลือกโฟลเดอร์

  6. บนเมนู เทอร์มินัล ให้เลือก เทอร์มินัลใหม่

    คุณจะใช้คําสั่ง .NET CLI เพื่อสร้างแอปคอนโซลใหม่

  7. ที่พรอมต์คําสั่งของแผงเทอร์มินัล ให้ป้อนคําสั่งต่อไปนี้:

    dotnet new console
    
  8. ปิดแผงขั้วต่อ

ตรวจทานแอปพลิเคชันตัวอย่าง

ใช้ขั้นตอนต่อไปนี้เพื่อโหลดและตรวจทานแอปพลิเคชันตัวอย่าง

  1. เปิดไฟล์ Program.cs

  2. บนเมนู มุมมอง ให้เลือก ชุดคําสั่ง

  3. ที่พรอมต์คําสั่ง ให้ป้อน .net: g จากนั้นเลือก .NET: สร้าง Assets สําหรับการสร้างและดีบัก

  4. แทนที่เนื้อหาของไฟล์ Program.cs ด้วยโค้ดต่อไปนี้:

    // 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. ใช้เวลาสักครู่เพื่อตรวจสอบรหัส

    โปรดสังเกตว่า แอปพลิเคชันทํางานต่อไปนี้:

    1. คําสั่งระดับบนสุดใช้Console.ReadLine()คําสั่ง เพื่อได้รับค่าสําหรับ lowerBound และupperBound

    2. คําสั่งระดับบนสุดจะผ่าน lowerBound และ upperBound เป็นอาร์กิวเมนต์เมื่อเรียกใช้ AverageOfEvenNumbers เมธอด

    3. เม AverageOfEvenNumbers ธอด จะทํางานต่อไปนี้:

      1. ประกาศตัวแปรท้องถิ่นที่ใช้ในการคํานวณ
      2. ใช้การforวนรอบเพื่อหาผลรวมจํานวนคู่ระหว่าง lowerBound และupperBound ผลรวมจะจัดเก็บไว้ในsum
      3. นับจํานวนรวมตัวเลขในผลรวม จํานวนจะถูกจัดเก็บไว้ในcount
      4. จัดเก็บค่าเฉลี่ยของตัวเลขที่รวมในตัวแปรที่ averageชื่อ ค่าของ average จะถูกส่งกลับ
    4. คําสั่งระดับบนสุดพิมพ์ค่าที่ส่งกลับโดย AverageOfEvenNumbers คอนโซลแล้วหยุดการดําเนินการชั่วคราว

กําหนดค่าดีบักสภาพแวดล้อม

แอปพลิเคชันตัวอย่างจะอ่านข้อมูลป้อนเข้าของผู้ใช้จากคอนโซล แผง DEBUG CONSOLE ไม่สนับสนุนการอ่านข้อมูลป้อนเข้าจากคอนโซล คุณจําเป็นต้องอัปเดตไฟล์ launch.json ก่อนที่คุณจะสามารถเรียกใช้แอปพลิเคชันนี้ในตัวดีบัก

  1. ใช้มุมมอง EXPLORER เพื่อเปิดไฟล์ launch.json

  2. ในไฟล์ launch.json ให้ console อัปเดตแอตทริบิวต์ดังนี้:

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

    ค่าเริ่มต้นสําหรับ console แอตทริบิวต์คือ internalConsoleซึ่งสอดคล้องกับแผง DEBUG CONSOLE น่าเสียดายที่แผงคอนโซล DEBUG ไม่สนับสนุนการป้อนข้อมูลของคอนโซล การตั้งค่า integratedTerminal จะสอดคล้องกับแผง TERMINAL ซึ่งสนับสนุนอินพุตและเอาต์พุตของคอนโซล

  3. บันทึกการเปลี่ยนแปลงของคุณไปยังแฟ้ม launch.json แล้วปิดแฟ้ม

  4. บนเมนูเรียกใช้รหัส Visual Studio เลือกเริ่มการดีบัก

  5. สลับไปยังแผงขั้วต่อ

  6. ที่พร้อมท์ "ผูกด้านล่าง" ให้ใส่ 3

  7. ที่พร้อมท์ "bound ด้านบน" ให้ใส่ 11

  8. โปรดสังเกตว่าแอปพลิเคชันจะแสดงข้อความต่อไปนี้จากนั้นหยุดชั่วคราว:

    The average of even numbers between 3 and 11 is 7.
    
  9. เมื่อต้องการออกจากแอปพลิเคชัน ให้กด Enter

แสดงข้อยกเว้นในวิธี AverageOfEvenNumbers

เม AverageOfEvenNumbers ธอด คาดว่าจะมีขอบสูงสุดที่มากกว่าขอบต่ําสุด ข้อผิดพลาด DivideByZero เกิดขึ้นถ้าขอบล่างมากกว่าหรือเท่ากับขอบสูงสุด

คุณจําเป็นต้องอัปเดต AverageOfEvenNumbers เมธอด เพื่อแสดงข้อยกเว้นเมื่อขอบด้านล่างมากกว่าหรือเท่ากับขอบสูงสุด

  1. ใช้เวลาสักครู่เพื่อพิจารณาวิธีที่คุณต้องการแก้ไขปัญหา

    ตัวเลือกหนึ่งคือการตัดการคํานวณaverageภายในtryบล็อกรหัสและcatchDivideByZeroข้อยกเว้นเมื่อเกิดขึ้น คุณสามารถเถียงข้อยกเว้น แล้วจัดการได้ในรหัสการโทร

    ตัวเลือกอื่นคือการประเมินพารามิเตอร์อินพุตก่อนที่จะเริ่มการคํานวณ หาก lowerBound มากกว่าหรือเท่ากับ upperBoundคุณสามารถโยนข้อยกเว้นได้

    การประเมินพารามิเตอร์และโยนข้อยกเว้นก่อนที่จะเริ่มการคํานวณเป็นตัวเลือกที่ดีกว่า

  2. พิจารณาชนิดข้อยกเว้นที่จะโยน

    มีข้อยกเว้นสองชนิดที่สอดคล้องกับปัญหา:

    • ArgumentOutOfRangeException - ควรแสดง ArgumentOutOfRangeException ชนิดข้อยกเว้นเฉพาะเมื่อค่าของอาร์กิวเมนต์อยู่นอกช่วงค่าที่สามารถอนุญาตได้ตามที่กําหนดโดยวิธีการเรียกใช้ แม้ว่า AverageOfEvenNumbers ไม่ได้กําหนดช่วงที่สามารถอนุญาตได้สําหรับ lowerBound หรือ upperBoundค่าของ lowerBound จะหมายความถึงช่วงที่อนุญาตสําหรับupperBound
    • InvalidOperationException: ควรแสดง InvalidOperationException ชนิดข้อยกเว้นเฉพาะเมื่อเงื่อนไขการใช้งานของเมธอดไม่สนับสนุนการเสร็จสิ้นที่สําเร็จของการเรียกเมธอดเฉพาะ ในกรณีนี้ เงื่อนไขการทํางานจะถูกสร้างขึ้นโดยพารามิเตอร์อินพุตของวิธีการ

    เมื่อคุณมีชนิดข้อยกเว้นสองชนิดขึ้นไปให้เลือก ให้เลือกชนิดข้อยกเว้นที่เหมาะสมกับปัญหานั้นอย่างใกล้ชิดยิ่งขึ้น ในกรณีนี้ ข้อยกเว้นสองชนิดจะสอดคล้องกับปัญหาดังกล่าว

    เมื่อคุณมีข้อยกเว้นสองชนิดหรือมากกว่าที่จัดแนวให้สอดคล้องกับปัญหาเท่าๆ กัน ให้เลือกชนิดข้อยกเว้นที่มีขอบเขตแคบที่สุด ชนิด ArgumentOutOfRangeException ข้อยกเว้นมีขอบเขตไปยังอาร์กิวเมนต์ที่ส่งผ่านไปยังเมธอด ชนิด InvalidOperationException ข้อยกเว้นถูกกําหนดขอบเขตสําหรับเงื่อนไขการใช้งานของเมธอด ในกรณีนี้ ArgumentOutOfRangeException ชนิดข้อยกเว้นมีขอบเขตแคบกว่า InvalidOperationException ชนิดข้อยกเว้น

    เม AverageOfEvenNumbers ธอด ควรแสดง ArgumentOutOfRangeException ข้อยกเว้น

  3. ที่ด้านบนของ AverageOfEvenNumbers วิธีการ หากต้องการตรวจสอบปัญหา bound ด้านบน ให้อัปเดตโค้ดของคุณดังนี้:

    if (lowerBound >= upperBound)
    {
    
    }
    
    int sum = 0;    
    
  4. หากต้องการสร้างและแสดง ArgumentOutOfRangeException ข้อยกเว้น ให้ if อัปเดตบล็อกโค้ดดังนี้:

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

    เส้นรหัสนี้จะเริ่มต้นอินสแตนซ์ใหม่ของ ArgumentOutOfRangeException คลาส ด้วยชื่อของพารามิเตอร์ป้อนเข้าที่ทําให้เกิดข้อยกเว้นและข้อความแสดงข้อผิดพลาดที่ระบุ

จับข้อยกเว้นในรหัสการโทร

เมื่อใดก็ตามที่เป็นไปได้ ควรจับข้อยกเว้นในระดับสแตกการโทรที่สามารถจัดการได้ ในแอปพลิเคชันตัวอย่างนี้ คุณสามารถจัดการพารามิเตอร์ของ AverageOfEvenNumbers วิธีการ ในวิธีการเรียกใช้ (คําสั่งระดับบนสุด) ได้

  1. เลื่อนขึ้นไปยังคําสั่งระดับบนสุด

  2. หากต้องการใส่ AverageOfEvenNumbers การเรียกเมธอดและ Console.WriteLine คําสั่งภายใน try บล็อกโค้ด ให้อัปเดตโค้ดของคุณดังนี้:

    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. หากต้องการสร้างส่วนคําสั่งที่เกี่ยวข้อง catch ให้ป้อนโค้ดต่อไปนี้:

    catch(ArgumentOutOfRangeException ex)
    {
    
    }
    
  4. ใช้เวลาสักครู่เพื่อพิจารณาว่าคุณอาจจัดการกับข้อยกเว้นได้อย่างไร

    ในการจัดการข้อยกเว้นนี้ โค้ดของคุณต้องทําสิ่งต่อไปนี้:

    • อธิบายปัญหาให้ผู้ใช้ทราบ
    • ขอรับค่าใหม่สําหรับupperBound
    • เรียก AverageOfEvenNumbers โดยใช้ ใหม่upperBound
    • ดําเนินการต่อไปยังcatchข้อยกเว้นถ้ารายการใหม่upperBoundที่ให้ไว้ยังคงน้อยกว่าหรือเท่ากับlowerBound

    การดําเนินการต่อไปยัง catch ข้อยกเว้นจําเป็นต้องวนรอบ เนื่องจากคุณต้องการเรียกใช้ AverageOfEvenNumbers เมธอด อย่างน้อยหนึ่งครั้ง จึงควรใช้การ do วนรอบ

  5. หากต้องการล้อมรอบ try บล็อก และ catch ภายในการ do วนรอบ ให้อัปเดตโค้ดของคุณดังต่อไปนี้:

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

    whileจําเป็นต้องมีนิพจน์เพื่อกําหนดเงื่อนไขการออกของการdoวนรอบ เป็นการยากที่จะระบุเงื่อนไขก่อนที่จะกําหนดเนื้อหาของ do บล็อกรหัส การ catch บล็อกรหัสให้เสร็จสมบูรณ์จะช่วยให้คุณกําหนด while นิพจน์ที่จําเป็น

  6. หากต้องการอธิบายปัญหาให้กับผู้ใช้และรับบล็อกโค้ดใหม่ upperBoundให้อัปเดตบล็อกโค้ดของคุณ catch ดังนี้:

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

    บล็อกรหัสที่อัปเดต catch จะอธิบายถึงปัญหาและต้องให้ผู้ใช้ใส่ขอบเขตด้านบนใหม่ อย่างไรก็ตาม จะเกิดอะไรขึ้นถ้าผู้ใช้ไม่มีค่าที่ผูกสูงสุดที่ถูกต้อง จะเกิดอะไรขึ้นถ้าผู้ใช้ต้องออกจากรอบ แทนที่จะใส่ค่า

  7. หากต้องการให้ตัวเลือกแก่ผู้ใช้เพื่อออกจากการวนรอบ แทนที่จะป้อนขอบด้านบนใหม่ ให้อัปเดตบล็อกโค้ดของคุณ catch ดังนี้:

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

    บล็อกรหัสที่อัปเดตแล้ว catch มีเส้นทางสองเส้นทาง เส้นทาง "ออก" และเส้นทาง "ขอบสูงสุด" ใหม่

  8. ใช้เวลาสักครู่เพื่อพิจารณา while นิพจน์ที่จําเป็นสําหรับ do รอบ

    ถ้าผู้ใช้ใส่ "ออก" ที่พร้อมท์ โค้ดควรออกจากรอบ ถ้าผู้ใช้ป้อนขอบสูงสุดใหม่ การวนรอบ ควรดําเนินต่อ นิพจน์ while ที่ประเมินว่าสามารถใช้บูลีนได้ เช่น:

    while (exit == false);
    

    นิพจน์ที่ while เสนอจะสร้างลักษณะการทํางานต่อไปนี้:

    • รอบ do จะยังคงทําซ้ําตราบเท่าที่บูลีนexitเท่ากับfalse
    • รอบ do จะหยุดการวนซ้ําทันทีที่บูลีนexitเท่ากับtrue
  9. หากต้องการสร้างอินสแตนซ์ของตัวแปรบูลีนที่ exitชื่อ และใช้ exit เพื่อตั้งค่าเงื่อนไขการออกของการ do วนรอบ ให้อัปเดตโค้ดของคุณดังนี้:

    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. บันทึกโค้ดที่อัปเดตแล้วของคุณ

  11. บนเมนูเรียกใช้ เลือกเริ่มการดีบัก

  12. สลับไปยังแผงขั้วต่อ

  13. ที่พร้อมท์ "ผูกด้านล่าง" ให้ใส่ 3

  14. ที่พร้อมท์ "bound ด้านบน" ให้ใส่ 3

  15. โปรดสังเกตว่าเอาต์พุตต่อไปนี้จะแสดงในแผงเทอร์มินัล:

    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. ที่พร้อมท์สําหรับขอบด้านบนใหม่ ให้ใส่ 11

  17. โปรดสังเกตว่าเอาต์พุตต่อไปนี้จะแสดงในแผงเทอร์มินัล:

    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. เมื่อต้องการออกจากแอปพลิเคชัน ให้กด Enter

ยินดีด้วย! คุณถูกโยน จับได้สําเร็จ และจัดการข้อยกเว้น

สรุป

นี่คือสิ่งสําคัญบางอย่างที่ต้องจําจากหน่วยนี้:

  • ตรวจสอบให้แน่ใจว่าได้กําหนดค่าดีบักสภาพแวดล้อมของคุณเพื่อสนับสนุนข้อกําหนดของแอปพลิเคชันของคุณ
  • รหัสเมธอด ควรมีข้อยกเว้นเมื่อตรวจพบปัญหาหรือเงื่อนไข
  • ควรจับข้อยกเว้นที่ระดับในสแต็คการโทรซึ่งสามารถแก้ไขได้