C#例外處理


異常(例外)是在執行程式期間出現的問題。 C# 異常是對程式執行時出現的異常情況的響應,例如:除以零的算術運算。

異常提供了將控制從程式的一個部分轉移到另一個程式的方法。 C# 例外處理建立在四個關鍵字上:trycatchfinallythrow

  • trytry塊標識一個特定異常被啟用的程式碼塊。try塊之後有一個或多個catch塊。
  • catch:程式在處理問題的程式中的某個位置使用例外處理程式捕獲異常。catch關鍵字表示捕獲異常。
  • finallyfinally塊用於執行給定的一組語句,無論丟擲異常還是丟擲異常。例如,如果開啟檔案,則不管是否引發異常,都必須關閉該檔案。
  • throw:當出現問題時,程式會丟擲異常。這是使用throw關鍵字完成的。

語法

假設一個塊引發異常,一個方法使用trycatch關鍵字的組合來捕獲異常。try/catch塊放在可能會產生異常的程式碼周圍。try/catch塊中的程式碼被稱為受保護程式碼,並且使用try/catch的語法如下所示:

try
{
   // statements causing exception
}catch( ExceptionName e1 ){
   // error handling code
}catch( ExceptionName e2 ){
   // error handling code
}catch( ExceptionName eN ){
   // error handling code
}finally{
   // statements to be executed
}

可以列出多個catch語句來捕獲不同型別的異常,以防try塊在不同情況(case)下引發多個異常。

C# 異常類

C# 異常由類表示。 C# 中的異常類主要直接或間接地從System.Exception類派生。 從System.Exception類派生的一些異常類是System.ApplicationExceptionSystem.SystemException類。

System.ApplicationException類支援應用程式生成的異常。因此,程式員定義的異常應該從這個類派生出來。

System.SystemException類是所有預定義系統異常的基礎類別。

下表列出了一些從System.SystemException類派生的一些預定義的異常類:

異常類 描述
System.IO.IOException 處理I/O錯誤
System.IndexOutOfRangeException 處理當方法參照陣列索引超出範圍時生成的錯誤。
System.ArrayTypeMismatchException 處理型別與陣列型別不匹配時生成的錯誤。
System.NullReferenceException 處理從參照空(null)物件而產生的錯誤。
System.DivideByZeroException 處理除以零產生的錯誤。
System.InvalidCastException 處理型別轉換過程中產生的錯誤。
System.OutOfMemoryException 處理由於空閒記憶體不足而產生的錯誤。
System.StackOverflowException 處理由於空閒記憶體不足而產生的錯誤。
System.StackOverflowException 處理堆疊溢位產生的錯誤。

處理異常

C# 以trycatch塊的形式提供了例外處理的結構化解決方案。使用這些塊,核心程式語句與錯誤處理語句分離。

這些錯誤處理塊使用trycatchfinally關鍵字實現。下面是一個除以零條件發生異常時的異常:

using System;
namespace ErrorHandlingApplication
{
   class DivNumbers
   {
      int result;
      DivNumbers()
      {
         result = 0;
      }
      public void division(int num1, int num2)
      {
         try
         {
            result = num1 / num2;
         }
         catch (DivideByZeroException e)
         {
            Console.WriteLine("Exception caught: {0}", e);
         }
         finally
         {
            Console.WriteLine("Result: {0}", result);
         }
      }
      static void Main(string[] args)
      {
         DivNumbers d = new DivNumbers();
         d.division(25, 0);
         Console.ReadKey();
      }
   }
}

當上述程式碼被編譯並執行時,它產生以下結果:

Exception caught: System.DivideByZeroException: Attempted to divide by zero. 
at ...
Result: 0

使用者定義的異常

您也可以定義自己的異常。使用者定義的異常類派生自Exception類。以下範例演示如何建立一個自定義異常:

using System;
namespace UserDefinedException
{
   class TestTemperature
   {
      static void Main(string[] args)
      {
         Temperature temp = new Temperature();
         try
         {
            temp.showTemp();
         }
         catch(TempIsZeroException e)
         {
            Console.WriteLine("TempIsZeroException: {0}", e.Message);
         }
         Console.ReadKey();
      }
   }
}

public class TempIsZeroException: Exception
{
   public TempIsZeroException(string message): base(message)
   {
   }
}

public class Temperature
{
   int temperature = 0;
   public void showTemp()
   {
      if(temperature == 0)
      {
         throw (new TempIsZeroException("Zero Temperature found"));
      }
      else
      {
         Console.WriteLine("Temperature: {0}", temperature);
      }
   }
}

當上述程式碼被編譯並執行時,它產生以下結果:

TempIsZeroException: Zero Temperature found

丟擲物件

如果直接或間接派生自System.Exception類,則可以丟擲一個物件。可以在catch塊中使用throw語句將當前物件丟擲:

Catch(Exception e)
{
   ...
   Throw e
}