往往我們在寫程式碼的時候,總是會在運作中遇到某些問題而導致程式崩潰。這並不是程式設計人員的水平不行,而是由業務邏輯,作業系統,或者電腦等其它設備出現問題而造成,比如在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) 異常的內容,更多相關內容請關注PHP中文網(www.php.cn)!