2017-04-05 79 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的目的是将多个异常合并到一个异常对象中。可能有几个内部异常,其中一些可能也是聚合异常。所以你应该扁平化聚合异常并检查它的所有内部异常。


您可以将'展开'部分放入扩展方法中以提高代码的可读性。