你们可能都知道,在 C# 中以这种方式捕获并重新抛出异常是邪恶的,因为它会破坏堆栈跟踪:
try
{
if(dummy)
throw new DummyException();
}
catch (DummyException ex)
{
throw ex;
}
在不丢失堆栈跟踪的情况下重新抛出异常的正确方法是:
try
{
if(dummy)
throw new DummyException();
}
catch (DummyException ex)
{
throw;
}
唯一的问题是我收到很多编译警告:“变量‘ex’已声明但从未使用过”。如果你有很多这些,有用的警告可能会隐藏在垃圾中。所以,这就是我所做的:
try
{
if(dummy)
throw new DummyException();
}
catch (DummyException)
{
throw;
}
catch(AnotherException ex)
{
//handle it
}
这似乎可行,但我想知道重新抛出未设置为变量的异常是否有任何缺点。 .net 如何威胁这一点?
提前致谢
编辑: 我已经稍微更改了我的代码以使我想做的事情更清楚,因为有些人误解了
最佳答案
I'd like to know if there is any downside of re-throwing an exception that is not set to an variable.
不,完全没有缺点。仅当您想在代码中引用异常时才需要变量,但由于您不需要使用 throw
语句来执行此操作,因此您根本不需要变量。
而且您在尝试消除“嘈杂”的编译器警告方面的想法完全正确。他们倾向于隐藏您确实想要修复的重要错误,并且获得干净的构建始终很重要。最好的解决方案是简单地重写代码以使用无参数的 catch
子句。
但是,请注意,在我看到的 82% 的情况下*,编写使用 throw
的代码是错误的。你通常不应该捕获你不知道如何处理的异常,你唯一打算的“处理”策略是重新抛出它们。在某些情况下,即使使用 throw
也会重置调用堆栈,从而导致您丢失重要的调试信息。还有更好的替代方法来记录异常以捕获/重新抛出。您可以在以下问题的答案中找到更多信息:
- Main method code entirely inside try/catch: Is it bad practice?
- what can lead throw to reset a callstack (I'm using "throw", not "throw ex")
让异常冒泡并集中处理它们绝对没有错。要记住的规则是您不应该使用异常来进行流量控制。但是在低级代码中抛出异常并在 UI 代码中向用户显示错误消息在堆栈的更高层并没有错。阅读微软的 Best Practices for Handling Exceptions获取一些一般提示。
* 略大于the percent of statistics that are made up on the spot .
关于C# - 重新抛出异常而不将其设置为变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5858835/