我有以下代码:
try
{
OnInitialize();
}
catch (PageObjectLifecycleException exception)
{
exception.OldLifecycleState = CurrentLifecycleState;
exception.RequestedLifecycleState = LifecycleState.Initialized;
throw exception;
}
我捕获异常,向其添加更多数据,然后重新抛出它。 Resharper警告我(正确)可能需要重新抛出并建议将其更改为:
throw;
但我想知道:这会正确地重新抛出修改后的例外或未经修改的原始例外吗?
编辑:回应“试一试”评论:我是C#的新手,来自C ++。在C ++中,你经常会在这样的角落情况下发现未定义的行为,我感兴趣的是我想要的是它的正式工作方式。
答案 0 :(得分:24)
我知道已经选择了答案但是这里有关于这个主题的更多信息。
try {
// code
}
catch(Exception e) {
throw e;
}
编译成IL时的上述代码将产生对throw
的调用,将对处理的异常的引用作为参数传递。您可能已经知道,您可以从代码中的任何位置调用throw
来引发异常。
try {
// code
}
catch(Exception e) {
throw;
}
编译成IL时的上述代码将产生对rethrow
的调用。这与throw
不同,因为rethrow
用于表示处理异常的块由于某种原因决定不处理它,因此应该向更高阶的catch块提供责任(下一个)。
rethrow
方法保留当前的调用堆栈跟踪,以便可以跟踪异常的来源。但是,throw
方法启动新的调用堆栈跟踪。一旦你理解了两种方法的用途,我认为这是有道理的。
根据我的经验,当你因为某些原因想要抛出异常时(例如对象的验证失败)你会使用throw exception;
,并且在执行某些操作后你会在catch语句中使用throw;
日志记录(即,在将异常处理职责传递到更高级别之前,您仍然可以访问验证失败的对象中的有用信息)。
在您的示例中,我建议如果您需要向异常添加更多信息,您可以创建一个全新的异常并提升它。因此,您将使用throw exception;
方法,其中“exception”是包含额外信息和最初抛出的异常的新异常。
希望有所帮助!
詹姆斯
答案 1 :(得分:19)
您可以将额外信息添加到数据中并使用throw
重新抛出异常,以便保持其原始格式和callstack
try
{
...
}
catch (PageObjectLifecycleException exception)
{
exception.Data.Add("additional data", "the additional data");
throw;
}
答案 2 :(得分:8)
它将抛出对修改后的异常的引用。
但是我不确定这是不是很好的编程风格。考虑创建一个新的异常并将PageObjectLifecycleException添加为其内部异常。这样处理代码可以确定它是否具有正确的附加信息。
答案 3 :(得分:2)
当前的异常被重新抛出,虽然我不确定你的模式是一个非常好的和可维护的模式。