C# .NET中throw和throw ex之间的区别是什么?

12
有人能简要说明一下throwthrow ex之间的区别吗?我看到throw会存储先前的异常,但不理解这一行。
可以举个例子简要说明吗?

3
有没有throw和throw ex之间的区别?throw;语句会抛出当前异常,并保持堆栈跟踪不变。throw ex;语句会抛出一个新的异常,其中包含先前异常的信息,并可能更改堆栈跟踪。在catch块中捕获到异常时,使用throw;可以使堆栈跟踪更容易理解,因为它不会更改原始异常的信息。然而,如果你想要记录原始异常并且能够访问其完整的堆栈跟踪,则需要使用throw ex;。 - Random
1
catch块中,不带参数的throw用于重新抛出引起catch的异常。 - Jodrell
2个回答

30
是的- throw 重新抛出被捕获的异常,并保留堆栈跟踪。throw ex 抛出相同的异常,但是重置堆栈跟踪到该方法。
除非您想要重置堆栈跟踪(即将公共调用者与库的内部工作隔离开来),否则throw通常是更好的选择,因为您可以看到异常的起源。
我还要提到“中转”catch块:
try
{
   // do stuff
}
catch(Exception ex)
{
    throw;
}

没有意义。这与根本没有try/catch的行为完全相同。


5
如果在抛出异常前加入日志记录,这样做并不是无意义的。我经常会这样使用它。 - Evgeni
18
@Eugene 你是正确的,但在我抛出(异常)之前我没有任何东西 - 这就是我想要说明的。 - D Stanley

5

throw会重新抛出原始异常;

throw ex会创建一个新的异常,因此堆栈跟踪会改变。通常意义不大,一般情况下你应该只是抛出异常,或者创建一个新的异常并将其抛出,例如:

// not a great code, demo purposes only
try{
File.Read("blah");
}
catch(FileNotFoundException ex){
throw new ConfigFileNotFoundException("Oops", ex);
}

我在多个场合使用过这种模式,即 throw new Exception...,通常只有在被现有代码逼到绝境时才会使用。如果我有时间/权限更改上游代码,我会尝试重构以避免需要使用此模式。然而,我偶尔也会在全新的代码中使用此模式。 - Andrew Steitz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接