【问题标题】:Catch exception not of a type捕获不是类型的异常
【发布时间】:2019-05-02 07:39:14
【问题描述】:

在捕获不是以下类型的异常时是否有区别:

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

和:

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

【问题讨论】:

  • 第一个 sn-p 将捕获 TaskCanceledException 的所有异常,第二个 sn-p 将捕获除 TaskCanceledException 之外的所有异常
  • 它们可以有不同的执行顺序 finally 子句放在 try 块内:tio.run/…
  • @PetSerAI 有趣的例子,你能提供更多关于这种行为的参考吗,所以在过滤器的 catch 中,finally 在所有异常块的最后执行?在没有过滤器的情况下,这是嵌套的?
  • 这两种方法在第二个 CLR(检查 ILDASM)中的实现方式不同,首先是 when 部分被执行,并在此基础上进入 catch 块。看看:weblogs.asp.net/dixin/c-6-0-exception-filter-and-when-keyword
  • @peeyushsingh 系统首先搜索一个catch子句,可以处理异常。这样做时,系统会执行异常过滤器来检查catch 是否适用。只有这样嵌套的finally 子句才会被执行。这一切都在specification,虽然它有点过时了。在异常过滤器成为 C# 的一部分之前。另外,您可以阅读this

标签: c#


【解决方案1】:

是的,有。

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

与第二个选项相比,第一个选项更正确。尽管您不应该抛出任何异常并远离它们,除非它完全破坏了交易。最重要的是,在抛出异常的 TaskCanceledException 捕获块下面放置一个异常类型的捕获块有什么意义?当您使用带有异常类型的 catch 时,您基本上是在告诉“我想处理所有异常”,但同时您在异常情况下会通过一个异常。要么抛出原始异常,要么处理它们。

希望这是有道理的。

【讨论】:

    【解决方案2】:

    参考此链接Stackoverflow

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

    catch (SomeSpecificExceptionType e) {...}
    

    when 子句允许您将此过滤器扩展到泛型表达式。

    因此,当异常类型不足以确定是否应在此处处理异常时,您可以使用 when 子句。

    【讨论】:

    • 这不回答问题
    【解决方案3】:

    Dixin's Blog 用代码示例和 VS 截图解释了区别。

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

    【讨论】:

      猜你喜欢
      • 2018-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-08
      • 2019-05-06
      • 2015-11-17
      • 1970-01-01
      相关资源
      最近更新 更多