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#异常过滤器?的主要内容,如果未能解决你的问题,请参考以下文章

如何在OnExceptionAsync c#中获取引发异常的方法名称[重复]

在 C# 中处理纯虚函数调用

Servlet过滤器——异常捕获过滤器

从位图到布隆过滤器,C#实现

Win32 异常过滤器使用与异常上报分析等

Win32 异常过滤器使用与异常上报分析等