C#异常过滤器?
Posted
技术标签:
【中文标题】C#异常过滤器?【英文标题】:C# exception filter? 【发布时间】:2011-05-15 04:05:45 【问题描述】:C# 是否支持编译过滤器?过滤器是如何工作的?它们有什么作用?
像反射器一样将过滤器反编译为
尝试 catch(Exception e) when (?)
【问题讨论】:
你可以添加一个更好的定义或你想要的过滤器的例子:) ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf, #23.3:如何处理异常 另见:***.com/questions/181188/… 查看此页面***.com/questions/4269189/… ;) 【参考方案1】:在 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 文档的链接。
【讨论】:
好的,所以 filter 基本上只是一个 if 语句,如果不满足它会重新抛出它? 不,它有细微的不同,因为如果真正的过滤器决定处理异常,它甚至不会捕获它,而使用 if 的解决方法会捕获并重新抛出它。这与堆栈展开相关的语义略有不同。 运行时也不同。过滤器在 catch 块之前运行,即使这些过滤器在调用堆栈中定义得更深。 这个答案不再是最新的。 C# 5 确实 支持异常过滤器。看我的回答。 C# 5 不支持异常过滤器。 C# 6 可以,但尚未正式发布。【参考方案2】:从 C# 6 开始,您现在可以执行此操作。
try …
catch (MyException e) when (myfilter(e))
…
这与在catch
块中使用if
语句不同,使用异常过滤器不会展开堆栈。
【讨论】:
【参考方案3】: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
【参考方案4】:
在捕获异常时,如果您想以不同的方式处理异常,则可以使用异常过滤器-- 在 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
【讨论】:
以上是关于C#异常过滤器?的主要内容,如果未能解决你的问题,请参考以下文章