介紹C# 6.0新功能-「例外狀況篩選條件」(exception filters)介紹,將會敘述如何使用這方便的語法糖。
C# 6.0發表時間:2015年7月,始於.NET Framework 4.6,Visual Studio 2015。
這個功能是用在try...catch...
中。一般時候catch
中的條件,是只有抓到指定錯誤才會執行,但是現在有例外的篩選條件可以增加更多條件,以進行各種例外發生時的處理。
在catch的變數後面,增加個:when
+ (條件)
,也就是變成when (XXX)
,當when
的條件滿足時將會動作後續的作業,如果不是的話就會忽略,繼續下一步。也就是說在catch
條件中滿足了例外回傳型別,但是還有「附加條件」也就是「if
」條件概念,當兩者都是為true的時候,就會執行動作。
例如:
catch (System.Net.Http.HttpRequestException e) when (e.Message.Contains("301"))
{
Console.WriteLine("Error");
}
當發生(HttpRequestException e)
的例外時,他的e
(也就是型別為HttpRequestException
的個體)的錯誤訊息內文要包含「301」,才會執行Console.WriteLine("Error")
這一句。如果不是的話就離開,就跟if
處理判斷一模一樣。
- 仿效微軟的範例:
using System;
public class Program
{
public static void Main()
{
try
{
string s = null;
Console.WriteLine(s.Length);
} catch (Exception e) when (LogException(e))
{
Console.WriteLine("e:"+e.Message);
Console.WriteLine("Test");
}
catch(Exception e)
{
Console.WriteLine("Test:"+e.Message);
}
Console.WriteLine("Exception must have been handled");
}
private static bool LogException(Exception e)
{
Console.WriteLine($"\tIn the log routine. Caught {e.GetType()}");
Console.WriteLine($"\tMessage: {e.Message}");
return true;
}
}
顯示結果為:
In the log routine. Caught System.NullReferenceException
Message: Object reference not set to an instance of an object.
e:Object reference not set to an instance of an object.
Test
Exception must have been handled
說明:
範例中,我們定義了一個string
為NULL
,而後面又執行Length
,會造成因為是空值而無法執行長度計算的狀況,這時就發生例外事件。這邊是使用萬用的Exception
去接這個事件。如果沒有when
,就直接執行大括號({}
)內的行為,如同最後一個catch(Exception e)
,就必定執行;當在後面增加when
,而我這邊會執行(LogException(e))
這個功能,而他的回傳值型態bool
,在目前範例中是回傳true
,也就是會執行這個Exception
動作,因此會印出錯誤訊息。然後這個執行完就會執行下一個Exception
。所以看output,可以看得出來先執行(LogException(e))
,接著是該Exception
內的動作,最後才是另一個Exception
動作。其中因為例外已經被前一個Exception
(萬用的例外事件)取走,所以第二個(Exception e)
就沒有資料。
因此動作就會是:
(LogException(e)) → 該exception內的動作 → 另一個exception動作(沒有資料)
如果把LogException
的回傳值改成false
會變成怎樣呢?就會執行(LogException(e))
內的動作,因為回傳值是false
,因此不會執行該exception
內的動作,也沒有取出這個例外資料。而後面exception
是萬用,所以也是被攔截到,而沒有when
條件,所以直接執行內部的作業。
所以動作會變成:
(LogException(e)) → (不動作) → 另一個exception動作(有資料)
因此有這樣的差異,在寫例外處理的時候要特別注意。
結論:
- 例外處理可以增加
when
的條件,就如同if
判斷式一樣,如果條件是true
就執行。 exception
如果已經被前面的catch
取得的話,後面就不會有例外的資料了。
參考資料:
- Docs:例外狀況篩選條件
~Copyright by Eyelash500~
IT技術文章:EY*研究院
iT邦幫忙:eyelash*睫毛
Blog:睫毛*Relax
Facebook:睫毛*Relax