关于c#:这两个try / catch / throw语句是否相同?

Are these 2 try/catch/throw statements the same?

本问题已经有最佳答案,请猛点这里访问。

给出以下陈述:

1
2
3
4
5
6
7
8
9
try
{
    ... some code ...
}
catch
{
    ... some cleanup code ...
    throw;
}

1
2
3
4
5
6
7
8
9
try
{
    ... some code ...
}
catch (Exception ex)
{
    ... some cleanup code ...
    throw ex;
}

这些操作是否相同,或者第一个操作是否会引发新的异常?


它们不一样。在第二个版本中,堆栈信息丢失。

更详细的解释如下:http://winterdom.com/2002/09/rethrowingexceptionsinc

从该网站:

In the [second piece of] code [..], you're not rethrowing ex, just merely beginning a new exception flow using the same exception object instance.


前者抛出原始异常;后者抛出新异常。它们的行为大体相同,只是前者保留原始堆栈跟踪,而后者仅具有从重新引发异常的位置开始的堆栈跟踪。


有两个不同之处

首先您是正确的,第二个会导致一个新的异常被一个新的堆栈跟踪抛出。这将导致您丢失宝贵的调试信息,而不应该这样做。执行第二个示例的正确方法是

1
2
3
4
5
6
7
8
9
try
{
    ... some code ...
}
catch (Exception) //You can include the"ex" if you need it in your cleanup code
{
    ... some cleanup code ...
    throw; //Don't use the"ex" here
}

第二个不同点是,第一个示例将捕获的异常数量非常少,而第二个示例将不会。主要是这些异常是从非clr-complient代码抛出的。无法从C代码中抛出非Exception派生的异常。

一件事是,如果您想在冒泡异常之前向它添加额外的信息,您可以抛出一个新的异常,并将旧的异常作为InnerException

1
2
3
4
5
6
7
8
9
try
{
    ... some code ...
}
catch (Exception ex)
{
    ... some cleanup code ...
    throw new MyCustomException("Some useful information", ex);
}


不,根据我的经验,虽然我尝试过两种解决方案,但第二种解决方案似乎只捕获指定的异常,尽管第一种解决方案可能捕获任何异常。希望这有帮助。