我在数据类中对catch块使用了以下模式:
} catch (OracleException e) {
log.Error(e, e);
ExceptionNotification.Show(e, "Platypus data not found for Platypus");
throw;
}
(“log”是log4net;之后是我们奇特的异常显示对话框。)
当我删除“throw”时,我得到“并非所有代码路径都返回值”
如果我到达异常块,我想要返回的对象(一个OracleDataTable,一个List,一个Dictionary<>或者一个自定义类,通常可能是null,或者最好不会感觉太好。什么可以我回到mollify编译器?
答案 0 :(得分:5)
声明返回类型的方法的每个代码路径都必须返回一个值或抛出异常。
如果你不想扔,你必须返回一个合适的值
} catch (OracleException e) {
log.Error(e, e);
ExceptionNotification.Show(e, "Platypus data not found for Platypus");
return SomeMeaningfulReturnValue;
}
但是,除非您可以返回的值对调用者实际上有意义(而不是返回 null 并且发明代码合同“null表示存在问题),我会坚持当异常出错时抛出异常的惯例。
答案 1 :(得分:2)
永远不要安抚编译器。把它们抛在脑后,让它们做你需要的,或者它们会超越自己。
编译器具有顺从性,就像被抛弃一样;你开始安抚他们的那一刻他们就会停止帮助你。他们中的一些甚至带着自己的桨。
如果你不得不问这个问题,你可能采取了错误的方法。 “吞下异常后返回的价值”的答案是“在这个地方吞噬这种异常时返回的价值显而易见的价值”。如果没有什么是明显的,那么就不应该吞下它(这同样适用于“在这个地方吞下这个例外之后,循环中的明显位置继续”)。然后仔细检查你的假设,因为“显而易见”的事情仍然是错误的。
你也应该清楚地评论任何吞咽,因为读取代码的人通常会假设它是错误的代码,除非你解释为什么不是这样,这通常是一件坏事。
您最好使用以下方法之一:
throw;
让异常消失。有东西处理它,或者某些东西没有处理,你得到一条错误消息和一个关闭(并不总是更糟糕的事情,取决于应用程序和错误的可能性)。
throw e;
哪个会抛出完全相同的异常(字面上是相同的实例)但会被视为来自您的代码而不是您调用的代码。这是很少正确的事情,有些人会告诉你这是完全错误的。我不同意,但我同意这种情况很少见 - 如吞咽,如果不是明显的选择,那几乎肯定是错误的选择,如果这是明显的选择,它可能仍然是错误的选择。
throw new ExceptionTypeAppropriateToThisMethodCall("a useful message");
OR
throw new ExceptionTypeAppropriateToThisMethodCall("a useful message", e);
在这里,您可以将异常转换为与您的方法提供给调用代码的服务更密切相关的内容。第二种形式包含内部异常以便诊断为善。
在某些情况下,只是杀死应用程序或卸载应用程序域可能是最好的选择,尽管这通常是因为在任何时候都没有处理异常。
答案 2 :(得分:1)
您可以返回什么取决于您希望函数在失败时执行的操作,或者该函数的调用者期望 fault 符号。
您可以将return null
(考虑到您的帖子)添加到
首先通知来电者返回值为null
第二个不传播异常(原因就是我想要的,就像我理解的那样)
答案 3 :(得分:1)
好吧,你要么抛出异常,要么返回一个值。这就是编译器抱怨的原因。您需要确定哪种模式在您的特定情况下最有效,采用它并确保编写调用代码以将其考虑在内。在这种特殊情况下,我可能只会传播异常,因为 捕获异常。除非你以某种方式补偿Oracle驱动程序的不正常行为,否则它可能不应该抛出异常。
“我没有找到任何数据”或类似的情况不等同于“我因为密码错误而无法登录数据库”。