C# 7 模式匹配
C# 7 Pattern Matching
假设我有以下异常过滤器
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 */ }
所以可能有一种方法可以做我想做的事。或者有没有?
您不能在同一范围内两次声明 ve
变量。但是您可以重写异常过滤器,以便 ValueException<int>
的变量只声明一次:
catch(Exception e)
when (((e as AggregateException)?.InnerException ?? e) is ValueException<int> ve)
{
// ...
}
如果异常被直接抛出或被包装到 AggregateException
中,这是您捕获异常的唯一方法。
请记住,AggregateException
的目的是将多个异常合并到一个异常对象中。可能有多个内部异常,其中一些也可能是聚合异常。所以你应该展平聚合异常并检查它的所有内部异常。
您可以将 'unwrapping' 部分放入扩展方法中以提高代码的可读性。
不如 Sergey 的解决方案好,但您也可以使用不同的名称并合并它们:
try
{
...
} catch (Exception e)
when (e is ValueException<int> ve1 ||
e is AggregateException ae
&& ae.InnerException is ValueException<int> ve2)
{
var exept = ve1 ?? ve2;
// do something with exept
}
如果您处理 ValueException 的 InnerExceptions 或一般的 ValueException 异常。
假设我有以下异常过滤器
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 */ }
所以可能有一种方法可以做我想做的事。或者有没有?
您不能在同一范围内两次声明 ve
变量。但是您可以重写异常过滤器,以便 ValueException<int>
的变量只声明一次:
catch(Exception e)
when (((e as AggregateException)?.InnerException ?? e) is ValueException<int> ve)
{
// ...
}
如果异常被直接抛出或被包装到 AggregateException
中,这是您捕获异常的唯一方法。
请记住,AggregateException
的目的是将多个异常合并到一个异常对象中。可能有多个内部异常,其中一些也可能是聚合异常。所以你应该展平聚合异常并检查它的所有内部异常。
您可以将 'unwrapping' 部分放入扩展方法中以提高代码的可读性。
不如 Sergey 的解决方案好,但您也可以使用不同的名称并合并它们:
try
{
...
} catch (Exception e)
when (e is ValueException<int> ve1 ||
e is AggregateException ae
&& ae.InnerException is ValueException<int> ve2)
{
var exept = ve1 ?? ve2;
// do something with exept
}
如果您处理 ValueException 的 InnerExceptions 或一般的 ValueException 异常。