捕获非类型的异常

时间:2019-05-02 07:39:14

标签: c#

在捕获非类型之间的异常时,是否存在区别:

try
{
    ...
}
catch (TaskCanceledException)
{
    throw;
}
catch (Exception exception)
{
    ...
}

和:

try
{
    ...
}
catch (Exception exception) when (!(exception is TaskCanceledException))
{
    ...
}

4 个答案:

答案 0 :(得分:2)

是的,有。

在第二段代码中,您将根据常规异常类型进行过滤。它不打算被过滤,如果抛出“ TaskCanceledException”,会发生什么?您没有处理它,它将升级为包含代码。您并不是真的想对“ Exception”类型的任何内容进行过滤,因为它是所有其他类型的异常的父级,并且是处理异常的最后一点。更好的选择是创建一个自定义异常,然后将其放在单独的catch块中,并在需要时对其进行过滤。

第一个选项比第二个选项更正确。尽管您不应该抛出任何异常并远离它们,除非这是一个彻底的交易破坏者。最重要的是,将带有异常类型的catch块放置在抛出异常的TaskCanceledException catch块的意义何在?您基本上是在说,使用具有Exception类型的catch时,“我想处理所有异常”,但是同时在特殊情况下您要通过一个异常。要么抛出原始异常,要么处理它们。

希望这很有道理。

答案 1 :(得分:1)

首先捕获所有TaskCanceledException的

第二个过滤(不是)TaskCanceledException的异常。

为什么?

异常过滤器比捕获和重新抛出异常更可取,因为过滤器会使堆栈不受损害。如果以后的处理程序转储了堆栈,则可以看到异常的原始来源,而不仅仅是重新抛出异常的最后一个地方。

这基本上意味着,当使用when子句时,您可以检查异常而不会拦截其过程。

答案 2 :(得分:0)

请参阅此链接Stackoverflow

Catch块已经允许您过滤异常的类型:

catch (SomeSpecificExceptionType e) {...}

when子句允许您将此过滤器扩展为通用表达式。

因此,在异常类型不够明显的情况下,可以使用when子句来确定是否应在此处处理异常。

答案 3 :(得分:0)

Dixin's Blog用代码示例和VS屏幕截图说明了区别。

异常过滤器不会展开堆栈,并且catch块不会展开。执行catch块时,此catch块的方法将成为堆栈的顶部框架。结果,当前方法调用的所有方法都从堆栈中删除。相反,异常过滤器对于运行时调试很有帮助。例如,如果执行了上面的Catch方法: