这两个try/catch/throw语句是相同的吗?
这里有两个不同之处。首先,你是正确的,第二个会导致一个新的异常被抛出,带有新的堆栈跟踪。这将导致你丢失有价值的调试信息,不应该这样做。第二个示例的正确方式是:
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兼容代码抛出。
我知道这是一些特殊的情况,我会在发布后进行研究并进行更正。我已经进行了更正。
这两个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语句可以更好地处理异常情况。
这两个try/catch/throw语句不相同。在第二个版本中,堆栈信息丢失了。
问题的原因是,在第二段代码中,并没有重新抛出异常ex,而只是使用了相同的异常实例开始了一个新的异常流。
解决方法可以通过在catch块中重新抛出异常来保留堆栈信息。以下是更详细的解释和来源:
http://winterdom.com/2002/09/rethrowingexceptionsinc
从该网站上的解释中我们可以得到如下信息:
在第二段代码中,你并没有重新抛出异常ex,而只是使用了相同的异常实例开始了一个新的异常流。