c# - 使用异常过滤器有什么好处以及何时应该使用它们?

标签 c# .net exception c#-6.0 .net-4.6

通过使用异常过滤器,比较旧的错误处理方式与新的错误处理方式,使用过滤器对我来说到底有什么好处以及何时应该使用它?在什么情况下我可以很好地利用这个新功能?

我已经阅读了有关展开堆栈的信息,但我仍然不明白我们无法以旧方式处理该问题的情况。请像我 5 岁一样解释一下。

try
{
    Foo.DoSomethingThatMightFail(null);
}
catch (MyException ex) when (ex.Code == 42)
{
    Console.WriteLine("Error 42 occurred");
}

对比

try
{
    Foo.DoSomethingThatMightFail(null);
}
catch (MyException ex)
{
    if (ex.Code == 42)
        Console.WriteLine("Error 42 occurred");
    else
        throw;
}

我知道这个问题还有其他版本,问题是,这个问题提到了我实际上找不到的好处,例如。

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.

经过一些测试后,我没有看到两者之间的区别,我仍然在重新抛出的地方看到异常。所以,或者信息没有得到确认,我不理解异常过滤器(这就是我问的原因),或者我做错了(如果我错了,也请纠正我)。

class specialException : Exception
{
   public DateTime sentDateTime { get; } = DateTime.Now;
   public int code { get; } = 0;
   public string emailsToAlert { get; } = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4f2a222e26230f2b20222e2621612c2022" rel="noreferrer noopener nofollow">[email protected]</a>";
}

然后:

try
{
   throw new specialException();
   //throw new Exception("Weird exception");
   //int a = Int32.Parse("fail");
}
catch (specialException e) when(e.code == 0)
        {
            WriteLine("E.code 0");
            throw;
            //throw e;
        }
catch (FormatException e) 
        {
            if (cond1)
            {
                WriteLine("cond1 " + e.GetBaseException().Message+" - "+e.StackTrace);
                throw;
            }
            throw;
        }
catch (Exception e) //when (cond2)
        {
            Console.WriteLine("cond2! " + e.Message);
            throw;
        }

最佳答案

我不明白保罗的回答。他可能是对的,也可能不是。

我绝对不同意亚历山大的回答。它不仅仅是语法糖。纯语法糖意味着它只是一种更简单的编写方式,并且执行不会改变。

但是,在这种情况下情况并非如此。正如托马斯·莱维斯克 points out in his blog ,异常过滤器不会展开堆栈。因此,在调试程序时,如果 try block 中抛出异常,则使用异常过滤器,您将能够看到 try block 中值的状态。如果您没有使用异常过滤器,您的代码将进入 catch block ,并且您将丢失有关 try block 中变量状态的信息。

请注意,我不是在谈论堆栈跟踪(它是与堆栈不同但相关的概念)。除非您明确地重新抛出异常,否则堆栈跟踪将保持不变,如 catch block 中的 抛出异常; 所示,其中 异常 是捕获的异常。

因此,虽然在某些情况下,您可以将其视为可能会或可能不会使您的代码更清晰的东西(取决于您对语法的看法),但它确实会改变行为。

关于c# - 使用异常过滤器有什么好处以及何时应该使用它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32620031/

相关文章:

java - Mockito 测试 void 方法抛出异常

c# - 在 MVVM 中解析 Prism 服务

c# - 随机 SQL 连接问题。工作,然后不工作,然后工作,然后 BAM!永远不会再工作?

.NET/WinForms - 清除 DataGridView 上的排序

c# - sqlConnection/Command 使用语句 + try/catch block

Java并发实践: BoundedExecutor implementation

c# - 删除包含项目的目录

c# - 如何使用 SWIG 生成的接口(interface)在 C# 中正确向下转换?

c# - 我应该在套接字接收和另一个之间使用 Thread.Sleep 吗?

.net - Silverlight 计时器类功能