25

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

主要的:

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

代码 1:

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

代码 2:

static void A()
{
    // Rethrow syntax.
    try
    {
        int value = 1 / int.Parse("0");
    }
    catch
    {
        throw;
    }
}
4

2 回答 2

54

我认为这里有两个问题。


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;
}

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

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

于 2012-05-29T20:12:46.180 回答
39

如果我们忽略“未使用的变量”警告,那么唯一一次有实际区别

catch {...}

catch(Exception ex) {...}

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

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

于 2012-05-29T21:33:18.753 回答