程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#異常處理及心得

C#異常處理及心得

編輯:C#入門知識

C sharp中的異常用於處理系統級和應用程序級的錯誤狀態,它是一種結構化、統一的類型安全的處理機制。c#的異常 機制非常類似於c++的異常處理機制,但是還是有一些重要的區別:

1,在 C# 中,所有的異常必須由從 System.Exception 派生的類類型的實例來表示。在 C++ 中,可以使用任何類型的任何值表示異常。

2,在 C# 中,利用 finally 塊可編寫在正常執行和異常情況下都將執行的終止代碼。在 C++ 中,很難在不重復代碼的情況下編寫這樣的代碼。

3,C# 中,系統級的異常如溢出、被零除和 null 等都對應地定義了與其匹配的異常類,並且與應用程序級的錯誤狀態處於同等地位。

1.1 導致異常的原因

可以以兩種不同的方式引發異常。

· throw 語句(第 ‎8.9.5 節)用於立即無條件地引發異常。控制永遠不會到達緊跟在 throw 後面的語句。

· 在執行 C# 語句和表達式的過程中,有時會出現一些例外情況,使某些操作無法正常完成,此時就會引發一個異常。例如,在整數除法運算(第 ‎7.8.2 節)中,如果分母為零,則會引發 System.DivideByZeroException。有關可能以此方式引發的各種異常的列表,請參見第 ‎16.4 節。

1.2 System.Exception 

System.Exception 類是所有異常的基類型。此類具有一些所有異常共享的值得注意的屬性:

· Message 是 string 類型的一個只讀屬性,它包含關於所發生異常的原因的描述(易於人工閱讀)。

· InnerException 是 Exception 類型的一個只讀屬性。如果它的值不是 null,則它所引用的是導致了當前異常的那個異常,即表示當前異常是在處理那個 InnerException 的 catch 塊中被引發的。否則,它的值為 null,則表示該異常不是由另一個異常引發的。以這種方式鏈接在一起的異常對象的數目可以是任意的。

這些屬性的值可以在調用 System.Exception 的實例構造函數時指定。

1.3 異常的處理方式

發生異常時,系統將搜索可以處理該異常的最近的 catch 子句(根據該異常的運行時類型來確定)。首先,搜索當前的方法以查找一個詞法上包含著它的 try 語句,並按順序考察與該 try 語句相關聯的各個 catch 子句。如果上述操作失敗,則在調用了當前方法的方法中,搜索在詞法上包含著當前方法調用代碼位置的 try 語句。此搜索將一直進行下去,直到找到可以處理當前異常的 catch 子句(該子句指定一個異常類,它與當前引發該異常的運行時類型屬於同一個類或是該運行時類型所屬類的一個基類)。注意,沒有指定異常類的 catch 子句可以處理任何異常。

找到匹配的 catch 子句後,系統將把控制轉移到該 catch 子句的第一條語句。在 catch 子句的執行開始前,系統將首先按順序執行嵌套在捕捉到該異常的 try 語句裡面的所有 try 語句所對應的全部 finally 子句。

如果沒有找到匹配的 catch 子句,則發生下列兩種情況之一:

· 如果對匹配的 catch 子句的搜索到達一個靜態構造函數(第 ‎10.12 節)或靜態字段初始值設定項,則在導致調用該靜態構造函數的代碼位置引發 System.TypeInitializationException。該 System.TypeInitializationException 的內部異常將包含最初引發的異常。

· 如果對匹配的 catch 子句的搜索到達最初啟動當前線程的代碼處,則該線程的執行就會終止。此類終止會產生什麼影響,應由實現來定義。

特別值得注意的是在析構函數執行過程中發生的異常。如果在析構函數執行過程中發生異常且該異常未被捕獲,則將終止該析構函數的執行,並調用它的基類的析構函數(如果有)。如果沒有基類(如 object 類型中的情況),或者如果沒有基類析構函數,則該異常將被忽略。

1.1 公共異常類
下列異常由某些 C# 操作引發。

1 System.ArrayTypeMismatchException

當存儲一個數組時,如果由於被存儲的元素的實際類型與數組的實際類型不兼容而導致存儲失敗,就會引發此異常。

1 System.DivideByZeroException

在試圖用零除整數值時引發。

1 System.IndexOutOfRangeException

在試圖使用小於零或超出數組界限的下標索引數組時引發。

1 System.InvalidCastException

當從基類型或接口到派生類型的顯式轉換在運行時失敗時,就會引發此異常。

1 System.NullReferenceException

在需要使用引用對象的場合,如果使用 null 引用,就會引發此異常。

1 System.OutOfMemoryException

在分配內存(通過 new)的嘗試失敗時引發。

1 System.OverflowException

在 checked 上下文中的算術運算溢出時引發。

1 System.StackOverflowException

當執行堆棧由於保存了太多掛起的方法調用而耗盡時,就會引發此異常;這通常表明存在非常深或無限的遞歸。

1 System.TypeInitializationException

在靜態構造函數引發異常並且沒有可以捕捉到它的 catch 子句時引發。

okay上文的內容就是對c#語言規范中對於異常處理的總結,下面總結一下我們這些新手經常出現的問題,請高手們補充,謝謝!
一、是否缺少 using 指令或程序集引用?
這是我在最近的探索中經常遇到的問題,雖然已經添加引用了,但是總會提示,很折磨的說,我總結了兩種較為通常的處理:
 1、修改:右擊類文件--屬性--生成操作--將“內容”改為“編譯”,然後重新生成,問題解決。
 2、另一種情況:項目中存在多個類庫,生成項目時提示 未能找到類型或命名空間名稱“XXXX”(是否缺少 using 指令或程序集引用?)  ,找到相應類庫中的“引用”文件夾,在其中添加對應的dll文件,單獨生成此類庫,若還是提示,則需要查看“引用”中是否有引用其他類庫所生成的dll文件,如果存在,則需要先確保生成該dll文件的類庫可以正常生成,以此類推,最終生成整個項目。
二、try,catch,finally
我是這樣理解的,先執行try裡面的語句,如果try裡面的語句拋出了錯誤,就會被catch捕獲,所以就會中斷try裡面語句的執行轉而執行catch裡面的語句,如果try裡面的語句都執行完了也沒有拋出錯誤,那麼catch裡的語句就沒有機會執行了。最後不論try順利運行完畢,還是try拋出了錯誤被catch語句捕獲並執行了catch的語句都要接著執行finally裡面的語句。但是總感覺缺點什麼~

 

這裡給出一個msdn上的最佳異常處理方法,希望會有所幫助。

http://msdn.microsoft.com/zh-cn/library/seyhszts.aspx

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved