2017-04-05 86 views
2

假設我有以下異常過濾器C#7模式匹配

try { 
    ... 
} catch (Exception e) when (e is AggregateException ae && ae.InnerException is ValueException<int> ve || e is ValueException<int> ve) { 
    ... 
} 

我可以簡單地寫了兩個獨立的catch塊,但我希望看到一個如何使用模式匹配功能來捕捉異常,要麼本身或包裝在AggregateException內。然而,在這裏,編譯器抱怨重新定義了ve,這是可以理解的。我曾經見過如下所示的模式匹配的變量相同的表達式內重複使用的情況下:https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/

if (o is int i || (o is string s && int.TryParse(s, out i)) { /* use i */ } 

所以有可能是一個辦法做到我想做的。或者在那裏?

+4

'我'在那裏使用但未聲明兩次。它在'o is int i''中聲明一次,在你的情況下你聲明瞭've'兩次。 –

+1

爲了說明以前的評論,如果表達式是:'(o是int i ||(o是字符串s && int.TryParse(s,out int i))'' – InBetween

+0

,您引用的示例不會將變量聲明兩次,但是您可以這樣做。嘗試像這樣:'(e是AggregateException ae && ae.InnerException是ValueException ve ||(ve = e作爲ValueException )!= null)' –

回答

4

在同一範圍內,您不能聲明ve變量兩次。但是你可以重寫異常過濾器所以ValueException<int>該變量只能聲明一次:

catch(Exception e) 
    when (((e as AggregateException)?.InnerException ?? e) is ValueException<int> ve) 
{ 
    // ... 
} 

這是你的一個班輪捕捉異常,如果它要麼直接拋出或者如果它包裹成AggregateException

請記住,AggregateException的目的是將多個異常合併到一個異常對象中。可能有幾個內部異常,其中一些可能也是聚合異常。所以你應該扁平化聚合異常並檢查它的所有內部異常。


您可以將'展開'部分放入擴展方法中以提高代碼的可讀性。