我們開發了函數,當函數的調用者在使用函數的時候,我們希望函數的調用者可以正确的使用函數,比如給予函數正确的參數值。但在實際的過程中,函數的調用者可能由于各種原因給予了錯誤的值。在這種情況下,我們需要向調用者抛出錯誤資訊,并中斷程式的執行,這個過程我們稱為異常。
程式必須能夠統一處理在執行期間發生的錯誤。公共語言運作庫提供了一個模型,以統一的方式通知程式發生的錯誤,進而為設計容錯軟體提供了極大的幫助。所有的 .NET Framework 操作都通過引發異常來訓示出現錯誤。
傳統上,語言的錯誤處理模型依賴于語言檢測錯誤和查找錯誤處理程式的獨特方式,或者依賴于作業系統提供的錯誤處理機制。運作庫實作的異常處理具有以下特點:
q 處理異常時不用考慮生成異常的語言或處理異常的語言。
q 異常處理時不要求任何特定的語言文法,而是允許每種語言定義自己的文法。
q 允許跨程序甚至跨計算機邊界引發異常。
與其他錯誤通知方法(如傳回代碼)相比,異常具有若幹優點。不再有出現錯誤而不被人注意的情況。無效值不會繼續在系統中傳播。不必檢查傳回代碼。可以輕松添加異常處理代碼,以增加程式的可靠性。最後,運作庫的異常處理比基于 Windows 的 C++ 錯誤處理更快。
抛出的異常有三種對象:
q System.Exception是最簡單的異常對象
q 抛出系統定義的最适合的異常對象
q 自定義的異常對象
以下的代碼是抛出System.Exception異常
/// <summary>
/// 計算長方形面積
/// </summary>
/// <param name="x">長</param>
/// <param name="y">寬</param>
/// <returns></returns>
public static double RectangleArea(int x, int y)
{
if(x<=0 || y<=0)
{
throw new System.Exception("參數無效!");
}
return x * y;
}
以下的代碼是抛出.NET Framework定義中最适合的異常
/// 計算正方形的面積
/// <param name="x">邊長</param>
public static double SquareArea(int x)
if(x<=0)
throw new System.ArgumentOutOfRangeException();
return x * x;
在RectangleArea函數中抛出的異常是最基本的異常。在SquareArea函數中抛出的是.NET Framework定義的ArgumentOutOfRangeException異常,該異常的含義是“當參數值超出調用的方法所定義的允許取值範圍時引發的異常”。
當我們給予錯誤的參數時
System.Console.WriteLine("該正方形的面積為{0}", SquareArea(-2));
将出現異常
以下是常用的異常,在決定抛出異常的時候,請先檢視.Net是否提供了合适的異常
異常類
用途說明
System.TimeoutException
逾時
System.TimeZoneNotFoundException
時區不正确
System.TypeLoadException
類型初始化不正确
System.UnauthorizedAccessException
IO錯誤
System.UriFormatException
Uri格式不正确
System.Threading.LockRecursionException
資源被鎖
System.OutOfMemoryException
記憶體不夠
System.StackOverflowException
嵌套死循環引起棧溢出
System.FormatException
提供的資料格式不正确
System.IndexOutOfRangeException
索引超出
System.RankException
數組緯度錯誤
當系統預定義的異常無法滿足我們的要求,我們可以建立自己的異常。比如我們編寫一個函數,該函數接受使用者的給予一個辨別,方法通過該辨別在資料庫中尋找相應的人員資訊,如果沒有找到則抛出一個異常。我們可以自己編寫一個異常。自定義異常需要了解.Net的異常層次結構:
有兩種類型的異常:由執行程式生成的異常和由公共語言運作庫生成的異常。另外,還有由應用程式或運作庫引發的異常的層次結構。
Exception 是異常的基類。若幹個異常類直接從 Exception 繼承,其中包括 ApplicationException 和 SystemException。這兩個類構成幾乎所有運作庫異常的基礎。大多數直接從 Exception 派生的異常不為 Exception 類添加任何功能。錯誤發生時,運作庫引發 SystemException 的适當派生類。這些錯誤是失敗的運作庫檢查導緻的,它們可在任何方法的執行過程中發生。如果設計建立新異常的應用程式,應從 Exception 類派生那些異常。不建議捕捉 SystemException,在應用程式中引發 SystemException 也不是好的程式設計做法。
我們定義自己的異常從SystemException類繼承
/// 員工沒有找到時引發的異常
public class EmployeeNotFoundException : System.SystemException
public EmployeeNotFoundException(string message)
: base(message)
public EmployeeNotFoundException()
一般異常的命名規則是以Exception為字尾。
在最後我們需要了解異常的處理一些内部概念。當異常發生的時候,.Net做了些什麼呢?異常發生時,運作庫開始執行由下列兩步組成的過程:
q 運作庫在數組中搜尋滿足下列條件的第一個受保護塊: 保護包含目前執行的指令的區域,而且包含異常處理程式或包含處理異常的篩選器。
q 如果出現比對項,運作庫建立一個 Exception 對象來描述該異常。然後運作庫執行位于發生異常的語句與處理該異常的語句之間的所有 Finally 語句或錯誤處理語句。請注意,異常處理程式的順序很重要:最裡面的異常處理程式最先計算。還請注意,異常處理程式可以通路捕捉異常的例程的局部變量和本地記憶體,但引發異常時的任何中間值都會丢失。
如果目前方法中沒有出現比對項,則運作庫搜尋目前方法的每一個調用方,并沿着堆棧一直向上查找。如果任何調用方都沒有比對項,則運作庫允許調試器通路該異常。如果調試器不能附加到該異常,則運作庫引發 UnhandledException 事件。如果沒有 UnhandledException 事件的偵聽器,則運作庫轉儲堆棧跟蹤并結束程式。換句話說就是:應用程式崩潰。
本文轉自shyleoking 51CTO部落格,原文連結:http://blog.51cto.com/shyleoking/805193