文章

第11天:例外處理

課程簡介

今天,我們將學習 例外處理(Exception Handling)在 C# 中的應用。例外處理是一種用來處理程式執行中錯誤的方法,能讓程式在發生錯誤時提供適當的反應或信息,而不至於直接崩潰。C# 提供了 trycatchfinallythrow 關鍵字來進行例外處理。


學習目標

  • 瞭解例外處理的基本概念
  • 學習如何使用 trycatchfinallythrow 來處理例外
  • 理解常見的內建例外類別
  • 學會如何創建自訂例外類別

課程內容

1. 什麼是例外處理?

例外(Exception)是程式在執行期間發生的錯誤或意外事件,可能導致程式無法正常執行。透過例外處理機制,我們可以捕捉並處理這些錯誤,以便程式在遇到錯誤時能提供合適的反應或重新嘗試。

2. 使用 try-catch-finally

C# 中,例外處理的基本結構是 try-catch-finally,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
try
{
    // 嘗試執行的程式碼
}
catch (ExceptionType ex)
{
    // 當發生指定類型的例外時執行的程式碼
}
finally
{
    // 無論是否發生例外,最後都會執行的程式碼(可選)
}

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try
{
    int dividend = 10;
    int divisor = 0;
    int result = dividend / divisor;
    Console.WriteLine("Result: " + result);
}
catch (DivideByZeroException ex)
{
    Console.WriteLine("Error: Division by zero is not allowed.");
}
finally
{
    Console.WriteLine("Execution completed.");
}

在這個範例中,由於除數為零,會拋出 DivideByZeroException,且 catch 區塊會捕捉這個例外並輸出相應的錯誤訊息。finally 區塊則會在無論例外是否發生的情況下執行。


3. 使用 throw

有時我們需要手動拋出例外,這可以使用 throw 關鍵字。這在您檢測到某種情況需要中止程式時特別有用。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void CheckAge(int age)
{
    if (age < 18)
    {
        throw new ArgumentOutOfRangeException("age", "Age must be 18 or older.");
    }
    else
    {
        Console.WriteLine("Access granted.");
    }
}

try
{
    CheckAge(15);
}
catch (ArgumentOutOfRangeException ex)
{
    Console.WriteLine("Error: " + ex.Message);
}

在這個範例中,CheckAge 方法會檢查年齡是否小於 18,如果是,則使用 throw 拋出 ArgumentOutOfRangeException 例外。這樣您可以控制程式在檢測到無效條件時停止執行。


4. 常見的例外類別

C# 中有許多內建的例外類別,常見的有:

  • System.Exception:所有例外的基底類別。
  • System.DivideByZeroException:當嘗試將一個數字除以零時拋出。
  • System.NullReferenceException:當引用一個 null 的物件時拋出。
  • System.IndexOutOfRangeException:當索引超出陣列或集合範圍時拋出。
  • System.InvalidOperationException:當執行無效操作時拋出。
  • System.ArgumentOutOfRangeException:當傳入的參數超出有效範圍時拋出。

範例:

1
2
3
4
5
6
7
8
9
try
{
    string[] fruits = { "Apple", "Banana", "Cherry" };
    Console.WriteLine(fruits[5]);  // 超出陣列範圍
}
catch (IndexOutOfRangeException ex)
{
    Console.WriteLine("Error: Index was out of range.");
}

此範例中,程式會嘗試存取不存在的陣列元素,進而引發 IndexOutOfRangeException,並在 catch 區塊中捕捉到該錯誤。


5. 自訂例外類別

您也可以創建自己的例外類別,以適應特定需求。自訂例外類別需繼承 System.Exception 或其子類別。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class NegativeNumberException : Exception
{
    public NegativeNumberException(string message) : base(message)
    {
    }
}

public void CheckPositiveNumber(int number)
{
    if (number < 0)
    {
        throw new NegativeNumberException("The number must be positive.");
    }
}

try
{
    CheckPositiveNumber(-5);
}
catch (NegativeNumberException ex)
{
    Console.WriteLine("Error: " + ex.Message);
}

在此範例中,我們創建了一個名為 NegativeNumberException 的自訂例外類別。當 CheckPositiveNumber 方法檢測到負數時,就會拋出這個例外,並在 catch 區塊中處理。


實作練習

  1. 撰寫除法程式並處理錯誤
    • Program.cs 中撰寫以下程式碼,讓使用者輸入兩個整數並進行除法運算。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      
      using System;
      
      class Program
      {
          static void Main(string[] args)
          {
              try
              {
                  Console.WriteLine("Enter the dividend:");
                  int dividend = Convert.ToInt32(Console.ReadLine());
      
                  Console.WriteLine("Enter the divisor:");
                  int divisor = Convert.ToInt32(Console.ReadLine());
      
                  int result = Divide(dividend, divisor);
                  Console.WriteLine("Result: " + result);
              }
              catch (DivideByZeroException ex)
              {
                  Console.WriteLine("Error: Cannot divide by zero.");
              }
              catch (FormatException ex)
              {
                  Console.WriteLine("Error: Please enter valid integers.");
              }
              finally
              {
                  Console.WriteLine("Thank you for using the division program.");
              }
          }
      
          public static int Divide(int dividend, int divisor)
          {
              return dividend / divisor;
          }
      }
      
  2. 執行程式
    • 執行程式,輸入不同情況的數字以測試例外處理是否正確運行:
      • 除數為 0。
      • 輸入無效的非數字字串。
    • 檢查程式是否提供了合適的錯誤訊息並執行 finally 區塊。

教學重點

  • 了解如何使用 try-catch-finallythrow 關鍵字來進行例外處理。
  • 探索常見的內建例外類別,並學會如何捕捉特定的例外。
  • 學習創建自訂例外類別,以解決特定的錯誤處理需求。

在下一節中,我們將學習如何使用 集合(Collections)來處理多個物件,並介紹 ListDictionary 等基本集合類別。

本文章以 CC BY 4.0 授權