什么';C#中各种try-catch之间的区别是什么

本文关键字:之间 try-catch 区别 是什么 什么 | 更新日期: 2023-09-27 18:02:24

可能重复:
尝试/接球/投掷和尝试/接球(e(/投掷之间的区别

原谅我的愚蠢,有人知道他们之间的区别吗?

 try
 {
      return 1 / 0;
 }
 catch (Exception)
 {
      throw;
 }

 try
 {
      return 1 / 0;
 }
 catch
 {
      throw;
 }

 try
 {
      return 1 / 0;
 }
 catch (Exception e)
 {
      throw(e);
 }

什么';C#中各种try-catch之间的区别是什么

  1. 将仅捕获并重新引发从Exception派生的异常
  2. 将捕获并重新引发任何异常。(编辑:由于CLRv2,所有异常都是从Exception派生的,因此这与1相同。见下面Eric Lippert的评论(
  3. 将捕获从Exception派生的任何异常并再次抛出,从而重置异常的堆栈跟踪

没有参数的catch子句可以捕获任何类型的异常。这有时被称为"一般"捕获条款。您可能永远不应该在生产应用程序中使用它,但我认为它有时可能对调试有用。它看起来像这样:

catch
{
}

catch子句还可以指定要捕获的特定异常类。您应该在应用程序中始终这样做,因为您只应该捕获您知道如何处理的异常。例如,您可能想要捕获一个DivideByZeroException;你可以这样做:

catch (DivideByZeroException)
{
}

当然,这会产生副作用,即您无法在catch块内引用异常类本身,因为您尚未将其分配给变量。如果需要在捕获的异常类的实例上调用属性或方法,则需要在catch语句中包含一个命名变量。这可能是你习惯看到的,看起来是这样的:

catch (DivideByZeroException ex)
{
    // do something with ex here
}

然后有两种方法来编写throw()语句,选择哪一种很重要

  1. 第一个看起来像这样:

    throw;
    

    它是在没有任何参数的情况下编写的,目的是重新抛出捕获的异常,同时保留堆栈跟踪和尽可能多的关于原始异常的信息
    (仍有一些边缘情况会导致您丢失堆栈跟踪,但通常情况下,这是比下面的备选方案更可取的。(

  2. 第二个选项传递一个异常类的实例作为参数,如下所示:

    throw(ex);
    

    或者这个:

    throw ex;
    

    重新抛出指定的异常,但如上所述,它的缺点是丢失了一些堆栈跟踪信息,这些信息告诉您是哪种方法负责抛出异常。除了抛出在同一方法中创建的异常对象外,很少会使用此方法。

    例如,如果您想捕获一个低级异常,并将其包装在一个新的异常对象中,供高级函数使用,则可以使用此表单。

前两个是等价的。

第三种通常应该避免:它从自己的堆栈帧中重新抛出异常,从而在过程中丢失有关原始帧的信息。

catch (Exception)-捕获从异常类派生的任何内容

catch (Exception e)-捕获从Exception类派生的任何内容,并将其分配给变量e,您可以使用该变量。

catch-接住任何投掷的东西。

示例1和2之间没有区别。两者都重新引发原始异常,并且都捕获通用Exception。如果您想捕获一个更具体的异常,例如DivisionByZeroException,您可以使用示例1。

对于最后一个示例,您没有重新抛出异常;但是抛出了与您捕获的相同的异常对象。这会导致异常堆栈跟踪被重新设置到抛出它的位置,这可能是一个问题,因为堆栈跟踪没有指向代码中实际发生错误的位置。

不同之处在于throw e;将抛出具有不同堆栈跟踪的异常。请参阅此已接受的答案。