C#异常过滤器?

时间:2010-11-24 15:06:43

标签: c# .net

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

像反射器一样将滤波器反编译为

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

4 个答案:

答案 0 :(得分:23)

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

try { … }
catch (MyException e) when (myfilter(e))
{
    …
}

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

答案 1 :(得分:6)

C#在C#6之前不支持VB之类的异常过滤器。至于它们的工作方式,请参阅Eric Lippert的"Finally" Does Not Mean "Immediately"

从C#6开始,支持例外过滤器,the C# FAQ demonstrates

try { … } 
catch (MyException e) when (myfilter(e)) 
{ 
    … 
}
  

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

     

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

     

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

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

感谢Mafii指向C#6文档的链接。

答案 2 :(得分:4)

C#中的异常过滤器支持在C#6中引入(Visual Studio" Dev14"):

try
{
    throw new ApplicationException("1");
}
catch (ApplicationException ex) when (ex.Message == "2")
{
    // this one won't execute.
}
catch (ApplicationException ex) when (ex.Message == "1")
{
    // this one will execute
}

答案 3 :(得分:0)

在捕获异常时,如果要以不同方式处理异常,则可以使用异常过滤器 - 在C#6.0之后
- 在VB 7.1之后使用WHEN

1)C#6.0后的C#样本

try
{
    throw new CustomException { Severity = 100 };
}
catch (CustomException ex) when (ex.Severity > 50)
{
    Console.WriteLine("*BING BING* WARNING *BING BING*");
}
catch (CustomException ex)
{
    Console.WriteLine("Whooops!");
}

注意:请记住订单很重要

2)C#6.0之前的C#样本

try
{
    throw new CustomException { Severity = 100 };
}
catch (CustomException ex)
{
   if (ex.Severity > 50)
    {
       Console.WriteLine("*BING BING* WARNING *BING BING*");
    }
   else
    {
       Console.WriteLine("Whooops!");
    }
}

因为这段代码等同于前一段代码。意思是,它们是等价的,对吗? ---“但不,他们不等同
注意:异常过滤器不会展开堆栈

Here

中了解更多信息