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