这两个try/catch/throw语句是相同的吗?

14 浏览
0 Comments

这两个try/catch/throw语句是相同的吗?

给定以下语句:

try
{
    ... 一些代码 ...
}
catch
{
    ... 一些清理代码 ...
    throw;
}

try
{
    ... 一些代码 ...
}
catch (Exception ex)
{
    ... 一些清理代码 ...
    throw ex;
}

这两种方式是相同的吗?还是第一种方式会导致抛出一个新的异常?

0
0 Comments

这里有两个不同之处。首先,你是正确的,第二个会导致一个新的异常被抛出,带有新的堆栈跟踪。这将导致你丢失有价值的调试信息,不应该这样做。第二个示例的正确方式是:

try
{
    ... some code ...
}
catch (Exception) //如果你在清理代码中需要它,可以包含“ex”
{
    ... some cleanup code ...
    throw; //不要在这里使用“ex”
}

第二个不同之处是,第一个示例会捕获第二个示例无法捕获的一小部分异常。主要是从非CLR兼容代码中抛出的异常。无法从C#代码中抛出非Exception派生的异常。

另外,如果你想在将异常上抛之前为其添加额外信息,可以抛出一个新的异常,并将旧异常作为InnerException

try
{
    ... some code ...
}
catch (Exception ex)
{
    ... some cleanup code ...
    throw new MyCustomException("Some useful information", ex);
}

实际上,CLR本身不会抛出非Exception异常。它们只能由其他语言中的外部非CLS兼容代码抛出。

我知道这是一些特殊的情况,我会在发布后进行研究并进行更正。我已经进行了更正。

0
0 Comments

这两个try / catch / throw语句是否相同?

这个问题的出现是由于两个try / catch / throw语句之间存在差异。第一个try / catch / throw语句会抛出原始异常,而第二个try / catch / throw语句会抛出一个新的异常。它们的作用基本相同,唯一的区别是,第一个try / catch / throw语句保留了原始异常的堆栈跟踪,而第二个try / catch / throw语句的堆栈跟踪仅从重新抛出异常的位置开始。

解决方法是,如果想保留原始异常的堆栈跟踪,可以使用第一个try / catch / throw语句。如果想要一个新的异常,并且只关心重新抛出异常的位置开始的堆栈跟踪,可以使用第二个try / catch / throw语句。

下面是两个try / catch / throw语句的示例代码:

第一个try / catch / throw语句:

try {
    // Some code that may throw an exception
} catch (Exception e) {
    // Handle the exception
    throw e;
}

第二个try / catch / throw语句:

try {
    // Some code that may throw an exception
} catch (Exception e) {
    // Handle the exception
    throw new Exception("New exception message");
}

根据具体需求,选择适合的try / catch / throw语句可以更好地处理异常情况。

0
0 Comments

这两个try/catch/throw语句不相同。在第二个版本中,堆栈信息丢失了。

问题的原因是,在第二段代码中,并没有重新抛出异常ex,而只是使用了相同的异常实例开始了一个新的异常流。

解决方法可以通过在catch块中重新抛出异常来保留堆栈信息。以下是更详细的解释和来源:

http://winterdom.com/2002/09/rethrowingexceptionsinc

从该网站上的解释中我们可以得到如下信息:

在第二段代码中,你并没有重新抛出异常ex,而只是使用了相同的异常实例开始了一个新的异常流。

0