捕获异常,添加数据并重新抛出它

时间:2012-02-27 15:29:50

标签: c# exception

我有以下代码:

try
{
   OnInitialize();
}
catch (PageObjectLifecycleException exception)
{
   exception.OldLifecycleState = CurrentLifecycleState;
   exception.RequestedLifecycleState = LifecycleState.Initialized;
   throw exception;
}

我捕获异常,向其添加更多数据,然后重新抛出它。 Resharper警告我(正确)可能需要重新抛出并建议将其更改为:

throw;

但我想知道:这会正确地重新抛出修改后的例外或未经修改的原始例外吗?

编辑:回应“试一试”评论:我是C#的新手,来自C ++。在C ++中,你经常会在这样的角落情况下发现未定义的行为,我感兴趣的是我想要的是它的正式工作方式。

4 个答案:

答案 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)

当前的异常被重新抛出,虽然我不确定你的模式是一个非常好的和可维护的模式。