简体   繁体   English

C#7模式匹配

[英]C# 7 Pattern Matching

Suppose I have the following exception filter 假设我有以下异常过滤器

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

I could have simply written two separate catch blocks, but I wanted to see how one could use the pattern matching feature to catch an exception that either is itself or is wrapped within an AggregateException . 我可以简单地写了两个独立的catch块,但我希望看到一个如何使用模式匹配功能来捕获异常,要么本身或内包装AggregateException Here, however, the compiler complains of a redefinition of ve , which is understandable. 然而,在这里,编译器抱怨重新定义ve ,这是可以理解的。 I have seen a case where a pattern matched variable is reused within the same expression as shown here: https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/ 我见过一个模式匹配变量在同一个表达式中重用的情况,如下所示: 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 */ }

so there is probably a way to do what I want. 所以可能有办法做我想做的事。 Or is there? 还是有吗?

You cannot declare ve variable twice in same scope. 您不能在同一范围内两次声明ve变量。 But you can rewrite exception filter so that variable for ValueException<int> will be declared only once: 但是您可以重写异常过滤器,以便ValueException<int>变量只声明一次:

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

It's your one-liner to catch exception if it either was thrown directly or if it is wrapped into AggregateException . 如果它被直接抛出或者被包装到AggregateException那么它就是你的单行程序来捕获异常。

Keep in mind that purpose of AggregateException is consolidating multiple exceptions into one exception object. 请记住, AggregateException目的是将多个异常合并到一个异常对象中。 There could be several inner exceptions, and some of them can be aggregate exceptions as well. 可能存在多个内部异常,其中一些也可能是聚合异常。 So you should flatten aggregate exception and check all of its inner exceptions. 因此,您应该压缩聚合异常并检查其所有内部异常。


You can put 'unwrapping' part into extension method to improve readability of your code. 您可以将“展开”部分放入扩展方法中,以提高代码的可读性。

Not as nice as Sergey's solution, but you can also use different names and coalesque them: 不像谢尔盖的解决方案那么好,但你也可以使用不同的名称并合并它们:

try 
{
    ...
} catch (Exception e) 
      when (e is AggregateException ae && ae.InnerException is ValueException<int> ve1 
                                                       || e is ValueException<int> ve2) 
{
    var exept = ve1 ?? ve2;

    // do something with exept
}

if you handle InnerExceptions of ValueException or general ValueException Exceptions the same. 如果您处理ValueException的InnerExceptions或一般ValueException异常相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM