我最近向一位同事发表声明:
NullReferenceExceptions永远不应该 被显式捕获
我用了从不……嗯。我自己从未见过合适的用例来捕捉它们,但我想检查是否有其他人有?
毕竟从来没有这么强烈的词......
我最近向一位同事发表声明:
NullReferenceExceptions永远不应该 被显式捕获
我用了从不……嗯。我自己从未见过合适的用例来捕捉它们,但我想检查是否有其他人有?
毕竟从来没有这么强烈的词......
这取决于为什么;请参阅 Eric Lippert 的博客条目。如果它们是“愚蠢的异常”,那么不 - 只需修复调用代码。在极少数情况下它们是“令人烦恼的异常”(即您调用的代码具有难以避免的陷阱),那么我想您必须这样做。
好吧,当你调用一个有缺陷的第三方库时,它偶尔会导致 nullrefs,如果你知道如何正确处理它们,捕获它们可能是个好主意。
现实生活中的例子:过去,我广泛使用了第三方编辑器提供的数据网格。他们有(或此时有)一个已确认的错误,该错误会在更新底层数据源中的某些数据时不时抛出一个 nullref(嵌套在他们的调用堆栈深处)。
我已经用这段代码处理了这种情况:
try
{
// do the update
}
catch (NullReferenceException)
{
try
{
// redo the update
}
catch (NullReferenceException ex)
{
// properly log the third party lib failure
}
}
顺便说一句,我的“日志”代码在 2 年内从未执行过:) 现在第三方编辑器已经解决了这个问题,我可能应该删除这段代码。
也许正确的报价是
如果您拥有引发异常的代码,则不应显式捕获 NullReferenceExceptions
你是对的,“从不”是一个强有力的词。
捕获 NullReferenceException(或 Java 的 NPE)将始终取决于代码的目的。
例如,如果您的应用程序要求即使在可能不确定的状态下继续处理(想想生命支持系统),或者如果您的代码不关心引用对象的状态(例如:批量处理数据,字面意思是抛出错误数据)。
不捕获这些类型的异常是一个很好的经验法则,但不是法律。
我不会说永远不会。例如,您可以捕获它以记录异常或将其从一个线程编组到另一个线程。在这两种情况下,都应该再次抛出异常。
正如 Marc Gravell 指出的那样,Eric Lippert 在他的博客上有一篇关于异常的非常好的文章。
我曾经不得不根据大约 15 个变量的值构建一个大字符串。我没有检查每一个是否为空,而是继续创建字符串,取消引用变量并捕获 NRE。老实说,这感觉很糟糕和顽皮,但它让我免于编写大量代码。