Catch vs Catch(例外e)和Throw vs Throw e

a12*_*773 24 c# try-catch

这两个代码示例是否相同?Catch and Catch(Exception e)具有相同的输出,如果我写ThrowThrow e,结果也是相同的.

主要:

try
{
    A();
    //B();
}
catch (Exception e)
{
    Console.WriteLine("{0} exception caught.", e);
}
Run Code Online (Sandbox Code Playgroud)

代码1:

static void A()
{
    try
    {
        int value = 1 / int.Parse("0");
    }
    catch (Exception e)
    {
        throw e;
    }
}
Run Code Online (Sandbox Code Playgroud)

代码2:

static void A()
{
    // Rethrow syntax.
    try
    {
        int value = 1 / int.Parse("0");
    }
    catch
    {
        throw;
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 53

我想这里有两个问题.


throw和之间有什么区别throw e;

我认为没有充分的理由写catch (Exception e) { throw e; }.这会丢失原始的堆栈跟踪.当您使用throw;原始堆栈跟踪时,将保留.这很好,因为这意味着更容易找到错误的原因.


catch和之间有什么区别catch (Exception e)

你的两个例子都是一样的,同样没用 - 它们只是捕获异常然后重新抛出它.一个小的区别是第一个示例将生成编译器警告.

变量'e'已声明但从未使用过

如果你在catch块中有一些其他代码实际上做了一些有用的事情,那么问这个问题会更有意义.例如,您可能希望记录异常:

try
{
    int value = 1 / int.Parse("0");
}
catch (Exception e)
{
    LogException(e);
    throw;
}
Run Code Online (Sandbox Code Playgroud)

现在有必要使用第一个版本,以便您可以引用捕获的异常.

如果您的catch块实际上没有使用异常,那么您可能希望使用第二个版本来避免编译器警告.

  • 也可以在不引入局部变量的情况下指定要捕获的异常类型(编译器抱怨从未使用过).你只需说:`catch(ArithmeticException){...}` (3认同)
  • Catch()也捕获未管理的异常 (2认同)

Mar*_*ell 36

如果我们忽略"未使用的变量"警告,那么唯一的时间就存在实际差异

catch {...}
Run Code Online (Sandbox Code Playgroud)

catch(Exception ex) {...}
Run Code Online (Sandbox Code Playgroud)

当一些非C#代码抛出非Exception异常时.C++可以抛出任何东西.在.NET 1.1中,您必须使用catch(否(Exception ex))来处理这些异常异常.然而,这是有问题的 - 尤其是,你无法看到抛出的东西!所以在.NET 2.0及更高版本中,这是默认包装的,所以即使C++抛出,比如说string- 你将它视为一个Exception子类.请注意,可以通过配置设置禁用此功能,但是:请勿执行此操作.不要管它!

已经提到了throw;vs 的问题throw ex;,并且涉及堆栈跟踪.您可以throw在两种情况下使用,从而保留原始堆栈跟踪.