介紹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
