凡事都可能有例外,當然自己的程式碼也是XD
有時候是自己的思慮不周寫了爛code,有時候是外部環境改變,有時候就是天時地利 加上人品不好(XD?) code就是掛了XD
讓我們來想想,當程式發生異常狀況導致無法繼續執行,這時候錯誤訊息直接顯示...
- 麻瓜使用者:陣列索引超出範圍?陣列是什麼?能吃嗎?阿我剛剛點的到底有沒有成功?天啊中毒了嗎?是不是要關機重開?(各種小劇場....)
- 駭客:喔~原來是錯在這個地方啊~(憋不住的笑意)
身為一個積極上進(?)的programer,這時候就會想,如果我可以在發生意料之外的錯誤時先做一些處理,或許可以避免掉一些麻煩?甚至先補救,不就沒人知道發生什麼事了嗎
這時候, try{...}catch{...}finally{...} 敘述就派上用場了!
=================================================================
try
{
//主程式/需要監控的區塊
}
catch(例外類別一 ex)
{
//例外類別一處理方法
}
catch(例外類別二 ex)
{
//例外類別二處理方法
}
...
catch(例外類別N ex)
{
//例外類別N處理方法
}
finally
{
//不管怎樣都會執行的區塊
}
說明:
來看看一個你如果處理陣列應該有遇到過(吧)的例外,IndexOutOfRangeException
static void Main(string[] args)
{
//上期發票中頭獎人名
string[] luckyman = { "總算有好事的小明", "路上撿到彩卷的阿花","被老婆盜刷的阿宏"};
Console.WriteLine(luckyman[3]);
Console.ReadKey();
}
因為luckyman[3]不存在,當你執行這段程式碼,程式會直接不讓你跑,IDE還會跳出這個錯誤訊息
於是我們改一下程式碼,順便看看ex是什麼
static void Main(string[] args)
{
try
{
Console.WriteLine(luckyman[3]);
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine(ex.ToString());//把ex印出來
}
Console.ReadKey();
}
當然如果要讓使用者看的話絕對不是丟給他錯誤訊息,於是再改一下程式碼
static void Main(string[] args)
{
try
{
Console.WriteLine(luckyman[3]);
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine("沒有第四個人了啦~");
}
finally
{
Console.WriteLine("不說了我要去對發票了");//不管有沒有遇到錯誤都會執行
}
Console.ReadKey();
}
就是這樣~這期發票9/25開獎囉~不說了我要去對發票了~
如果我明天沒有發文章...恩...你知道的
================================================================
常碰到的例外處理類別有以下(寫到這一篇6個也遇到5個了....),完整可以參考MSDN:
另外感謝下方小朱大大補充
類別 | 說明 |
---|---|
ArgumentOutOfRangeException | 引數超出有效值的範圍 |
DivideByZeroException | 整數或Decimal除法運算中的分母為零 |
IndexOutOfRangeException | 索引超出陣列或集合的範圍 |
InvalidOperationException | 方法呼叫在物件的目前狀態中無效 |
FormatException | 引數格式無效或複合格式字串格式(如:Datetime)不正確 |
NullReferenceException | 當嘗試對 Null 物件(未初始化)取值 |
InvalidCastException | Convert方法的轉型錯誤,如值域不足、型態錯誤...等 |
Exception | 執行時期所產生錯誤,可以捕捉所有例外 |
另外Exception(最後一格)這個錯誤類別範圍太粗略了要小心使用,若使用也應該放在最後一個catch,否則會有編譯錯誤。
================================================================
遇到特殊錯誤,系統沒有提供此判斷時,也可以另外寫程式來處理。以下示範指定ArgumentOutOfRangeException來作為例外類別。
一年有12個月,但不會有例外判斷會幫你判定輸入值控制在1-12
static void Main(string[] args)
{
int month = 0;
try
{
Console.WriteLine("請輸入月份");
month = Convert.ToInt32(Console.ReadLine());
if (month > 12 || month<1)
throw new ArgumentOutOfRangeException();//指定丟出這個例外類別,要new喔!
}
catch (ArgumentOutOfRangeException ex)
{
Console.WriteLine("沒有這個月份啦!我書讀得少不要騙我R");
}
Console.ReadKey();
}
當然也可以繼承Exception類別自創例外類別,但須用到繼承、覆寫等概念尚未學習我們這裡先不談,可以參考這篇文章
================================================================
發生錯誤要怎麼找到底錯在哪???
一直忘了介紹IDE這個好用的debug功能-設中斷點!
你可以在編輯程式碼區左列按一下加上紅點點
程式跑到這個點就會暫停一下,這時候你可以把游標移到想確認的地方做確認,例如到底有沒有讀到值等等
然後目光移到最上方工具列,可以選擇繼續執行或是逐步執行,可以更快找到程式碼到底哪裡有問題唷
=================================================================
MSDN-try-catch
書籍:
Visual C# 2017程式設計經典
從零開始學Visual C# 2015程式設計
if (month > 12 || month < 0) { } // month < 1就好囉~
這個地方有錯哦~
感謝!已修正XD
其實最常見的是 NullReferenceException,尤其是初入門的人愈容易碰到。
原因是存取一個未初始化的物件變數。
還有一種 InvalidCastException,在叫用 Convert 的方法做數值轉型時的問題,例如值域不足、格式不對 (字串轉數字、浮點數、布林值時) 等。
感謝大大!學到了!XD
string[] luckyman = { "總算有好事的小明", "路上撿到彩卷的阿花","被老婆盜刷的阿宏"};
這邊的 luckyman 好像是陣列形式 (中括號),這邊變成是尖括號了 ~