共用方式為


21 個例外狀況

21.1 一般

C# 中的例外狀況提供結構化、統一且類型安全的方式來處理系統層級和應用層級錯誤狀況。

21.2 例外狀況的原因

例外狀況可以透過兩種不同的方式擲回。

  • throw語句 (~13.10.6) 會立即且無條件地擲回例外狀況。 控件永遠不會在 之後 throw立即到達 語句。
  • 處理 C# 語句和表示式時所發生的特定例外狀況,會導致在無法正常完成作業的某些情況下擲回例外狀況。 如需可透過這種方式擲回的各種例外狀況清單,請參閱 <21.5 >。

    範例:如果分母為零,整數除法運算(~12.10.3) 會 System.DivideByZeroException 擲回 。 end 範例

21.3 System.Exception 類別

類別 System.Exception 是所有例外狀況的基底類型。 這個類別有一些值得注意的屬性,所有例外狀況都會共用:

  • Message 是類型的 string 只讀屬性,其中包含例外狀況原因的人類可讀取描述。
  • InnerException 是類型的 Exception唯讀屬性。 如果其值不是null,則會參考造成目前例外狀況的例外狀況。 (也就是說,目前例外狀況是在處理 的 catch 區塊中引發的 InnerException。否則,其值為 null,表示此例外狀況不是由另一個例外狀況所造成。 以這種方式鏈結在一起的例外狀況對象數目可以是任意的。

您可以在 對 實體 System.Exception建構函式的呼叫中指定這些屬性的值。

21.4 如何處理例外狀況

例外狀況是由 try 語句處理(~13.11)。

擲回例外狀況時(~21.2),系統會搜尋可處理例外狀況的最接近 catch 子句,如例外狀況的運行時間類型所決定。 首先,系統會搜尋目前的方法以語匯括住try的語句,並依序考慮語句的try相關聯catch子句。 如果失敗,則會搜尋呼叫目前方法的方法,以語匯括 try 住目前方法呼叫點的語句。 此搜尋會繼續執行,直到 catch 找到可以處理目前例外狀況的子句為止,方法是將相同類別或基類的例外狀況類別命名為擲回之例外狀況的運行時間類型。 catch不命名例外狀況類別的子句可以處理任何例外狀況。

找到相符 catch 子句之後,系統會準備將控制權傳送至 子句的第 catch 一個語句。 子句執行catch開始之前,系統會先依序執行與try語句相關聯的任何finally子句,比攔截到例外狀況的子句更巢狀。

如果找不到相符 catch 的子句:

  • 如果搜尋比 catch 對子句到達靜態建構函式 (~15.12) 或靜態字段初始化表達式,則會 System.TypeInitializationException 在觸發靜態建構函式調用的點擲回 。 的內部例外 System.TypeInitializationException 狀況包含原本擲回的例外狀況。
  • 否則,如果在完成項執行期間發生例外狀況,而且未攔截該例外狀況,則行為不會指定。
  • 否則,如果搜尋相符 catch 子句到達最初啟動線程的程序代碼,則會終止線程的執行。 這類終止的影響是實作定義。

21.5 常見例外狀況類別

特定 C# 作業會擲回下列例外狀況。

例外狀況類型 說明
System.ArithmeticException 在算術運算期間所發生的例外狀況 (例如 System.DivideByZeroExceptionSystem.OverflowException) 的基底類別。
System.ArrayTypeMismatchException 當存放區進入陣列失敗時擲回,因為預存專案的型別與陣列的類型不相容。
System.DivideByZeroException 嘗試將整數值除以零時擲回。
System.IndexOutOfRangeException 嘗試透過小於零或超出數位界限的索引編製數位索引時擲回。
System.InvalidCastException 當從基底類型或介面到衍生型別的明確轉換在運行時間失敗時擲回。
System.NullReferenceException 當使用參考的方式導致需要參考物件時 null 擲回。
System.OutOfMemoryException 嘗試設定記憶體時擲回 (透過 new) 失敗。
System.OverflowException checked 內容中的算術運算溢位時擲回。
System.StackOverflowException 當執行堆疊耗盡時擲回,因為呼叫太多擱置中;通常表示非常深或未繫結的遞歸。
System.TypeInitializationException 當靜態建構函式或靜態字段初始化表達式擲回例外狀況時擲回,而且沒有 catch 子句可攔截它時擲回。