有什么好处呢新的"例外滤波器QUOT;功能提供了? [英] What benefit does the new "Exception filter" feature provide?

查看:162
本文介绍了有什么好处呢新的"例外滤波器QUOT;功能提供了?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C#6有一个名为异常过滤



的语法是这样的新功能:

 赶上(Win32Exception除外)时(exception.NativeErrorCode == 0x00042)
{
//做的东西在这里
}

我不禁想知道的是,好处是比目前的方法:

 赶上(Win32Exception除外)
{
如果(exception.NativeErrorCode == 0x00042)
{
//这里做一些事情
}
}

它是一个大问题,即过滤卷曲之前发生托架?也许,相对于性能或安全性?


解决方案

异常过滤器功能在C#6.0提供了各种好处。下面是一些解释(我的感知重要性排序)




  • 功能奇偶 - 异常过滤器是在IL层面已经实现与其他.NET语言(VB.Net&安培; F#) [1] 和建设的C#和VB.Net新的编译器的(项目罗斯林)的一部分现有的语言,在其他缺乏许多功能被实施 [2]


  • 故障转储 - 异常过滤器不修改堆栈。这意味着如果它被倾倒(在故障转储),你就可以知道哪里异常最初抛出,而不是只有在它被重新引发(这是无关的实际问题) [3]


  • 调试 - 当一个异常进入块,重新抛出使用扔; ,并在堆栈中没有处理其他地方(和例外设置被设置为打破时异常是用户未处理)调试器将打破扔; 而不是在异常最初抛出(在它下面的例子就是将打破扔; ,而不是抛出新FileNotFoundException异常();


  • 多个 - 无一例外过滤器必须捕获该异常,检验一个条件,如果不符合扔; 除外。在重新抛出异常不会考虑任何其他块,即使异常满足所有这一切最终导致一个大的

     
    {
    抛出新FileNotFoundException异常();
    }
    赶上(FileNotFoundException异常E)
    {
    如果(e.FileName.Contains(仓鼠)!)
    {
    扔;
    }
    //处理
    }
    赶上(例外五)
    {
    //无法访问的代码
    }


  • 可读性 - 虽然你可以使用一个一网打尽有很多条件和catch 扔; 时,他们没有满足(而遭受修改堆栈),它更清楚有独立和独特块,其中每个在适当的方式处理一个特定的问题:

     尝试
    {
    }
    赶上(Win32Exception除外)时(exception.NativeErrorCode == 0x00042)
    {
    }
    赶上(Win32Exception除外)时,( exception.NativeErrorCode == 0x00011)
    {
    }
    赶上(IOException异常)
    {
    }


  • 滥用 - 您可以使用异常过滤器的方式来检查的异常没有处理它。虽然这不是一个主要好处这是一个很好的副作用。你可以有一个假回测井方法和一个空的块:

     私有静态布尔LogException(例外的例外)
    {
    Console.WriteLine(exception.Message);
    返回FALSE;
    }


    {
    }
    赶上(ArgumentException异常)时(LogException(例外))
    {
    / /可达代码。
    }




在最后,最的C#6.0的特点是小的改进和语法糖,虽然异常过滤器是不是一个非常大的功能它提供的功能在以前是不可能的。







  1. AC# 6.0语言预览




    另一个例外改善C#6.0 - 支持异常过滤器,带来的语言了最新的与其他.NET语言,即Visual Basic .NET和F#



  2. 语言功能在C#6和VB 14


  3. 新在C#6

    特点


    异常过滤器是最好捕获并重新抛出,因为他们离开堆栈一劫。如果异常后会导致堆栈转储,你可以看到它最初是从,而不仅仅是最后的地方它被重新引发出来。




C# 6 has a new feature called "exception filtering"

The syntax is like this:

catch (Win32Exception exception) when (exception.NativeErrorCode == 0x00042)  
{  
    //Do something here 
}  

I couldn't help but wonder what the benefit of that is over the current approach:

catch (Win32Exception exception)   
{
     if (exception.NativeErrorCode == 0x00042)
     {
          //Do something here 
     }
}

Is it a big deal that filtering happen before the curly bracket? Perhaps in relation to performance or security?

解决方案

The Exception Filters feature in C# 6.0 provides various benefits. Here's an explanation of some (ordered by my perceived importance)

  • Feature Parity - Exception filters were already implemented in the IL level and the other .Net languages (VB.Net & F#)[1] and as part of building the new compiler for C# and VB.Net (project "Roslyn") many features existing in one language and lacking in the other were implemented[2].

  • Crash Dumps - Exception filters don't modify the stack. which means that if it gets dumped (in a crash dump) you would be able to know where the exception was originally thrown and not only where it was rethrown (which is irrelevant to the actual problem)[3]

  • Debugging - When an exception enters a catch block, rethrown using throw; and isn't handled anywhere else in the stack (and the exception settings are set to break when the exception is user-unhandled) the debugger would break on throw; instead of where the exception is originally thrown (i.e. in the example below it would break on throw; and not throw new FileNotFoundException();)

  • Multiple catch Blocks - Without exception filters you must catch the exception, check a condition and if it isn't met throw; the exception. The rethrown exception doesn't consider any other catch blocks even if the exception satisfies all the conditions which ultimately results in a single big catch block

    try
    {
        throw new FileNotFoundException();
    }
    catch (FileNotFoundException e)
    {
        if (!e.FileName.Contains("Hamster"))
        {
            throw;
        }
        // Handle
    }
    catch (Exception e)
    {
        // Unreachable code
    }
    

  • Readability - While you could use a "catch all" catch block with many conditions and throw; when they are not met (while suffering the modification to the stack) it's much clearer to have separate and distinct catch blocks where each handles a specific problem in the appropriate way:

    try
    {
    }
    catch (Win32Exception exception) when (exception.NativeErrorCode == 0x00042)  
    { 
    }  
    catch (Win32Exception exception) when (exception.NativeErrorCode == 0x00011)  
    {  
    }
    catch (IOException)
    {  
    }
    

  • "Abuse" - You could use exception filters as a way to inspect an exception without handling it. While this is not a main benefit it's a nice side effect. You can have a false-returning logging method and an empty catch block:

    private static bool LogException(Exception exception)
    {
        Console.WriteLine(exception.Message);
        return false;
    }
    
    try
    {
    }
    catch (ArgumentException exception) when (LogException(exception))  
    {
        // Unreachable code.
    }
    

In conclusion, most of C# 6.0 features are small improvements and syntactic sugar, and while exception filters isn't a very big feature it does provide functionality that wasn't possible before.


  1. A C# 6.0 Language Preview

    The other exception improvement in C# 6.0—support for exception filters—brings the language up-to-date with other .NET languages, namely Visual Basic .NET and F#

  2. Languages features in C# 6 and VB 14

  3. New Features in C# 6

    Exception filters are preferable to catching and rethrowing because they leave the stack unharmed. If the exception later causes the stack to be dumped, you can see where it originally came from, rather than just the last place it was rethrown.

这篇关于有什么好处呢新的"例外滤波器QUOT;功能提供了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆