當我們在try block發生例外時,如果需要在catch block處理完例外後,要將原來的例外抛回呼叫端,大家是會用throw或是throw ex呢?雖然這2種語法皆可以把例外再抛回呼叫端,如果你在呼叫端攔到Exception時show ex.Message則都可以看到同樣的例外訊息,不過這2個語法還是有一點不一樣,以下列程式片段為例:
1: using System;
2:
3: namespace ConsoleApplication1
4: {
5: class Program
6: {
7: static void Main()
8: {
9: try
10: {
11: TestEx1();
12: }
13: catch (Exception ex)
14: {
15: Console.WriteLine("TestEx1:" + ex.ToString());
16: }
17:
18: Console.Read();
19: }
20:
21: static void TestEx1()
22: {
23:
24: try
25: {
26: int a = int.Parse("");
27: }
28: catch (Exception ex)
29: {
30:
31: throw ;
32: }
33: }
34:
35: }
36: }
如果你用throw ex,則在Main的ex.ToString中,所得到的內容如下:
TestEx1:System.FormatException: 輸入字串格式不正確。
於 ConsoleApplication1.Program.TestEx1() 於 C:\Users\Administrator\Desktop\ConsoleApplication3\ConsoleApplication3\Program.cs: 行 31
於 ConsoleApplication1.Program.Main(String[] args) 於 C:\Users\Administrator\Desktop\ConsoleApplication3\ConsoleApplication3\Program.cs: 行 11
堆疊最上層的行31是指throw ex那一行,而不是真正發生例外的int.Parse那一行;如果將程式的第31行throw ex改為throw,則ex.ToString則得到的例外內容如下:
TestEx1:System.FormatException: 輸入字串格式不正確。
於 System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
於 System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
於 System.Int32.Parse(String s) 於 ConsoleApplication1.Program.TestEx1()
於 C:\Users\Administrator\Desktop\ConsoleApplication3\ConsoleApplication3\Program.cs: 行 31
於 ConsoleApplication1.Program.Main(String[] args) 於 C:\Users\Administrator\Desktop\ConsoleApplication3\ConsoleApplication3\Program.cs: 行 11
有沒有發現例外發生的真正原因是從Int32.Parse一直到最底層StringToNumber(難怪int.Parse參數一定要傳string,原來是底層會先做字串轉數字動作),都有show出來.也就是當你用throw ex抛出例外時,.Net會清除原始的Stack再抛出例外,所以呼叫端看到的Stack是從throw ex那一行開始算,使用throw才能保留原始Stack的內容.
所以囉,最好還是使用throw而不要使用throw ex來抛出原例外,以免看不到真正發生的原因.
沒有留言:
張貼留言