【发布时间】:2011-05-15 04:05:45
【问题描述】:
C# 是否支持编译过滤器?过滤器是如何工作的?它们有什么作用?
像反射器一样将过滤器反编译为
尝试
{
}
catch(Exception e) when (?)
{
}
【问题讨论】:
-
你可以添加一个更好的定义或你想要的过滤器的例子:)
C# 是否支持编译过滤器?过滤器是如何工作的?它们有什么作用?
像反射器一样将过滤器反编译为
尝试
{
}
catch(Exception e) when (?)
{
}
【问题讨论】:
在 C# 6 之前,C# 不支持像 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 文档的链接。
【讨论】:
从 C# 6 开始,您现在可以执行此操作。
try { … }
catch (MyException e) when (myfilter(e))
{
…
}
这与在catch 块中使用if 语句不同,使用异常过滤器不会展开堆栈。
【讨论】:
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
}
【讨论】:
if 在 C#6 的最终版中已替换为 when
在捕获异常时,如果您想以不同的方式处理异常,则可以使用异常过滤器
-- 在 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
【讨论】: