c# 6引入了when關鍵字。when關鍵字是通過某些特定標準來過濾catch塊中的異常的一種方法。後來在c# 7中擴展到case語句。我們將介紹如何在異常處理中和case語句使用when關鍵字。
普通的Catch處理
假設您希望使用不同的標準處理相同類型的異常。一個常見的場景是HttpException。當您捕獲一個HttpException時,會返回一個響應代碼。根據響應代碼的不同,您可能需要採取不同的操作。
try
{
// do web call
}
catch(HttpException ex)
{
if(ex.WebEventCode >= 500)
{
HandleServerError(ex);
}
else if(ex.WebEventCode >= 400)
{
HandleNotFoundError(ex);
}
...
}
如您所見,處理錯誤涉及catch塊中的一系列if語句。這樣的代碼看起來很不優雅。如果涉及到嵌套異常出來會使可讀性變得更加困難,這使更加容易出現問題。
使用When關鍵字的Catch 處理
引入when關鍵字,會讓代碼變得優雅起來。讓我們使用when關鍵字來處理相同的邏輯。
try
{
// do web call
}
catch(HttpException ex) when (ex.WebEventCode >= 500)
{
HandleServerError(ex);
}
catch(HttpException ex) when (ex.WebEventCode >= 400)
{
HandleNotFoundError(ex);
}
將when關鍵字應用到相同的代碼會減少嵌套。看起來更直觀,所以它使catch塊的邏輯更容易理解。
在編寫本文時,when關鍵字在代碼styler中沒有被格式化為關鍵字。這恰恰也證明這個關鍵字並不廣為人知。這很不幸,因為它在很多情況下都很有用!
When關鍵字不僅僅只是能判斷異常
在when
語句中,可以評估的不僅僅是異常。這樣做實際上非常有用。看看下面的例子:
public void DoRecursion(int recurseCount = 3)
{
try
{
throw new Exception("recurse until 0");
}
catch(Exception e) when (recurseCount > 3 && e.Message == "recurse until 0")
{
DoRecursion(recurseCount--);
}
}
如您所見,評估catch異常之外的其他變量是很有用的。實際上,我今天使用它來實現對API的web調用的備份。
switch Case中使用When關鍵字
switch (item)
{
case type variable1:
// processing...
break;
case type variable2 when predicate:
// processing...
break;
default:
// processing...
break;
}
此 switch 非彼 switch,編譯後你會發現擴展的 switch 就是 as 、if 、goto 語句的組合體。同 is expressions 一樣,以前我們也能實
現只是寫法比較繁瑣並且可讀性不強。
模式匹配語法是想讓我們在簡單的情況下實現類似與多態一樣的動態調用,即在運行時確定成員類型和調用具體的實現。
結論
您應該開始在必須檢查異常以作出決定的場景中使用when關鍵字。我們不用太擔心其他不熟悉這個關鍵字的開發人員。when關鍵字很直觀,可會很快學會!但是,一定要注意在when表達式中的對象引用不能再出新的異常。
閱讀更多 程序你好 的文章