往往我們在寫代碼的時候,總會在運行中遇到某些問題而導致程式崩潰。這並不是編程人員的水平不行,而是由商務邏輯,作業系統,或者電腦等其它裝置出現問題而造成,比如在c#中經常用到user32.dll裡的一些方法,假如這個檔案被刪掉了,你的程式照樣運行不了。當然作為一個有水平的程式員總會在寫程式時是需要將各種情況都考慮進去的,水平越高考慮的情況就越多,而考慮的越多你的程式崩潰的機會就越少,健壯性就越好。
一般來說,程式運行不了會有兩種情況:
一是錯誤。它包括環境的錯誤(比如檔案缺少,檔案內容錯誤,導致與程式約定的不符合,系統版本不支援等等);記憶體操作錯誤(比如記憶體不足導致分配記憶體失敗);程式邏輯錯誤(這一般是流程錯誤導致程式得出了錯誤的結果等);
二是異常。異常是指程式由於當前流程的因素或意外行為導致無法運行。一般包括:
非法操作,使用者輸入了錯誤指令;輸入輸出異常,訪問外部裝置出現的非硬體性問題,比如讀寫硬碟時,結果將外部的虛擬光碟機,磁碟片等也當成硬碟使用,或者程式本身沒有問題,但是讀寫硬碟還是報出錯誤等;記憶體配置異常,記憶體不足時,導致無法建立新的對象。
總的來說,錯誤和異常有一個關鍵的區別,錯誤是不允許出現的,一旦出現就必須要修改程式,更改運行環境;而異常是程式的一部分,不論什麼程式或多或少都會遇到各類異常,異常出現程式就要處理異常,但是異常不應該影響程式繼續運行。對於錯誤則是出現了就修改。下面看下C#中異常的處理。
一般來說,為了保證程式不出錯,都會做很多判斷if...else,但是智者千慮必有一失,就算是大牛總不能讓程式面面俱到、所有情況都能想到。那麼這是我們就應該用到C#中的處理異常的方式。C#中採用的是抓拋模型來處理異常,當程式出現了異常後在處理異常的地方捕獲到這個異常對象。拋出的是一個Exception類或者其子類的對象,比如:
ArgumentException: 參數不合法時拋出此異常。
ArgumentNullException: 參數為null時拋出此異常。
ArgumentOutOfRangeException: 參數超出功能時拋出此異常。
捕獲異常格式如下:
try { //程式碼片段 } catch (Exception ex) { //處理異常 } finally { //最後一定執行的 }
try代碼塊中是可能出現異常的代碼,可以使用throw關鍵字拋出異常,也可以訪問任何可能會拋出異常的屬性或方法;
catch代碼塊用於捕獲要捕獲的異常,並包含處理該異常的代碼;
finally代碼塊表示異常處理結束後執行的程式碼片段,即finally中的程式碼片段總是被最後執行,而無論是否捕獲到了異常。
看看下面幾段代碼:
繼承自Exception直觀瞭解下Exeption類:
public class MySelfException : Exception { /// <summary> /// 預設構造器 /// </summary> public MySelfException() : base() { } /// <summary> /// 提供一個string類型的參數構造器,可設定自訂資訊 /// </summary> /// <param name="message"></param> public MySelfException(string message) : base(message) { } /// <summary> /// 用於傳入異常資訊,另外可以傳入該異常有哪個其它異常引發的 /// </summary> /// <param name="message"></param> /// <param name="innerException"></param> public MySelfException(string message, Exception innerException) : base(message, innerException) { } /// <summary> /// 覆蓋Message屬性,返回經過處理的異常資訊 /// </summary> public override string Message { get { return "有異常:" + base.Message; } } }
下面看下抓拋的過程:
public class Exceptions { public static void PersonInfo(string name, char sex, int age) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (sex != '男' && sex != '女') { throw new ArgumentException("sex只能為“男”或“女”"); } if (age <= 0 || age >= 150) { throw new ArgumentOutOfRangeException("age"); } Console.WriteLine(string.Format(@"name={0},sex={1},age={2}", name, sex, age)); } public static void Throwable(bool canThrow, int num) { if (canThrow) { throw new MySelfException("測試異常"); } Console.WriteLine(1 / num); Console.WriteLine("木有拋出異常"); } }
//調用:
class Program { static void Main(string[] args) { try { // Exceptions.PersonInfo(null, '男', 22); // Exceptions.PersonInfo("Purple", '呵呵', 22); Exceptions.PersonInfo("Purple", '男', 1000); //Exceptions.PersonInfo("Purple", '男', 22); Console.WriteLine("代碼執行無錯誤"); } catch (ArgumentNullException e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); } catch (ArgumentOutOfRangeException e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); } catch (ArgumentException e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); } Console.ReadLine(); } }
可以看到,在try代碼塊中,一旦程式運行到throw關鍵字,則立即停止運行其後的代碼,隨即跳轉到對應throw拋出異常物件類型的catch代碼塊中執行。所以抓拋模型是一種更為直觀和合理的異常處理方式。
以上就是C#基礎知識整理:基礎知識(13) 異常的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!