C#异常过滤器?

Wil*_*ill 11 .net c#

C#是否支持编译过滤器?过滤器如何工作或他们做什么?

像反射器一样反射滤波器

try
{
}
catch(Exception e) when (?)
{
}

Joe*_*Joe 23

从C#6开始,你现在可以做到这一点.

try { … }
catch (MyException e) when (myfilter(e))
{
    …
}
Run Code Online (Sandbox Code Playgroud)

这与使用块if内的语句不同catch,使用异常过滤器不会展开堆栈.


bdu*_*kes 6

在C#6之前,C#不支持VB之类的异常过滤器.至于它们是如何工作的,请参阅Eric Lippert的"最后"并不意味着"立即"

从C#6开始,支持异常过滤器,因为C#FAQ演示了:

try { … } 
catch (MyException e) when (myfilter(e)) 
{ 
    … 
}
Run Code Online (Sandbox Code Playgroud)

如果'if'[now when] 之后的括号表达式求值为true,则运行catch块,否则异常继续.

异常过滤器比捕获和重新抛出更可取,因为它们可以保持堆栈不受破坏.如果稍后的异常导致堆栈被转储,您可以看到它最初来自哪里,而不仅仅是它重新抛出的最后一个位置.

使用异常过滤器进行副作用也是一种常见且被接受的"滥用"形式; 例如伐木.他们可以在不拦截其路线的情况下检查"飞过"的异常.在这些情况下,过滤器通常会调用一个错误返回的辅助函数来执行副作用:

private static bool Log(Exception e) { /* log it */ ; return false; }
…
try { … }
catch (Exception e) when (Log(e)) {}
Run Code Online (Sandbox Code Playgroud)

感谢Mafii提供C#6文档的链接.

  • C#5**不支持异常过滤器.C#6确实没有正式发货. (4认同)
  • 不,它有微妙的不同,因为真正的过滤器甚至不会捕获它,如果它决定处理异常,而一个解决方案与if捕获并重新抛出它.这与堆栈展开相关的语义略有不同. (3认同)