C#是否支持编译过滤器?过滤器如何工作或者他们做了什么?
像反射器一样将滤波器反编译为
try { } catch(Exception e) when (?) { }
答案 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