2

我在我的数据类中使用以下模式捕获块:

} catch (OracleException e) {
    log.Error(e, e);
    ExceptionNotification.Show(e, "Platypus data not found for Platypus");
    throw;
}

(“日志”是 log4net;之后是我们花哨的异常显示对话框)。

当我删除“抛出”时,我得到“并非所有代码路径都返回值”

如果我到达异常块,我想要返回的对象(OracleDataTable、List、Dictionary<> 或自定义类,通常可能为 null,或者充其量感觉不太好。我可以返回什么来缓解编译器?

4

4 回答 4

5

声明返回类型的方法的每个代码路径都必须返回一个值或抛出一个异常。

如果你不想抛出,你必须返回一个合适的值

} catch (OracleException e) {
    log.Error(e, e);
    ExceptionNotification.Show(e, "Platypus data not found for Platypus");
    return SomeMeaningfulReturnValue;
}

但是,除非您可以返回的值对调用者实际上是有意义的(而不是说返回null并发明“null 表示存在问题”的代码协定),否则我会坚持在出现异常时抛出异常的约定错误的。

于 2012-08-16T22:01:18.683 回答
2

永远不要安抚编译器。领导他们,让他们做你需要的事情,否则他们会超越自己。

编译者有顺从的性格,喜欢被老板欺负;一旦你开始安抚他们,他们就会停止帮助你。他们中的一些人甚至自带桨。

如果你必须问这个问题,你可能采取了错误的方法。“吞下异常时返回什么值”的答案是“在这个地方吞下这个异常时要返回的值是显而易见的值”。如果没有什么明显的,那么它不应该被吞下(这同样适用于“在这个地方吞下这个异常后循环中明显的地方继续”)。然后仔细检查您的假设,因为“显而易见”的事情仍然可能是错误的。

您还应该清楚地注释任何吞咽,因为这通常是一件坏事,以至于任何阅读代码的人都会从假设它是坏代码开始,除非您解释为什么不是。

您最好使用以下方法之一:

throw;

让异常过去。有东西处理它,或者没有东西,你会收到一条错误消息和关闭(并不总是更糟糕的事情,取决于应用程序和错误的可能性)。

throw e;

这将引发完全相同的异常(实际上是相同的实例),但会被视为来自您的代码,而不是您调用的代码。这很少是正确的事情,以至于有些人会告诉你这是完全错误的。我不同意,但我同意这种情况很少见——比如吞咽,如果这不是明显的选择,那几乎肯定是错误的选择,如果是明显的选择,它可能仍然是错误的选择。

throw new ExceptionTypeAppropriateToThisMethodCall("a useful message");

或者

throw new ExceptionTypeAppropriateToThisMethodCall("a useful message", e);

在这里,您将异常转换为与您的方法提供给调用代码的服务更密切相关的东西。第二种形式包装了诊断良好的内部异常。

在某些情况下,仅仅终止应用程序或卸载应用程序域可能是最好的选择,尽管这主要是因为在任何时候都没有处理异常。

于 2012-08-16T22:34:52.613 回答
1

你能返回什么取决于你希望你的函数在失败时做什么,或者该函数的调用者期望什么,比如故障标志。

您可以添加return null(考虑您的帖子),

  • 首先通知调用者返回值是null

  • 第二不要传播异常(因为这是你想要的,据我所知)

于 2012-08-16T22:02:20.267 回答
1

好吧,您要么抛出异常,要么返回一个值。这就是编译器抱怨的原因。您需要确定哪种模式在您的特定情况下最有效,采用它并确保编写调用代码以将其考虑在内。在这种特殊情况下,我可能只会传播异常,因为您正在捕获异常。除非您以某种方式对 Oracle 驱动程序的不守规矩行为进行补偿,否则它可能不应该抛出异常。

“我没有找到任何数据”或类似情况不等同于“我无法登录数据库,因为密码错误”。

于 2012-08-16T22:06:32.447 回答