【问题标题】:When to raise an exception or return null?何时引发异常或返回 null?
【发布时间】:2012-10-16 08:16:31
【问题描述】:

我在数据访问层有几个函数

public Order RetrieveById(int id)
public List<Order> RetrieveByStatus(OrderStatus status)

现在我对异常引发有点困惑。

在 RetrieveById 函数的情况下,小于 1 的 id 是无效的 id,因此我想引发异常。而且我想为数据库中不存在的 Id 返回 null 。然后感觉我太复杂了。

在 RetrieveByStatus 的情况下,当数据库中没有该状态的数据时,我想返回一个空列表。

但是我看到有些人在 RetrieveById 不能返回任何东西时引发异常,但是 RetrieveByStatus 在没有记录时不应该引发异常,还是应该引发异常?

谁能帮我澄清一下这些概念?

【问题讨论】:

  • 另一种可能性是使用Order RetrieveByID(id)bool TryRetrieveByID(id, out Order) 模式。

标签: c# exception-handling


【解决方案1】:

在第一种情况下,我可能会去处理异常并自己处理,而不是返回 null。如果您的第一个方法以将返回的对象保存到 Order 引用的方式使用会怎样。很有可能NullReferenceException 被抛出,当有人试图调用该对象的方法或属性时。

对于第二种方法,我会按照一些人的建议选择一个空列表。

【讨论】:

    【解决方案2】:

    我希望尽可能避免返回 null,因为 NullRefExceptions 比特定异常(例如 OrderNotFoundException)要神秘得多。此外,当您必须不断期望实体为空时,代码会变得非常迟钝。无论如何,这应该是一个例外情况——如果数据库中不存在该 id,您从哪里获得该 id?

    在您怀疑这更有可能引发错误的情况下,您可以添加DoesObjectExistTryGet 类型的方法(甚至是扩展方法)。

    【讨论】:

    • 如果元素不存在时存在替代流程,您将强制调用该方法的代码捕获异常。我真的更喜欢 return null 并允许决定如何处理它。
    【解决方案3】:
    1. 首先阅读 MSDN:Creating and Throwing Exceptions (C# Programming Guide)。它列出了您应该抛出异常的两种情况,以及何时应该避免它。
    2. 还要考虑What is the real overhead of try/catch in C#?

    在任何情况下,您都必须处理 null 返回或抛出的异常


    就我自己而言,我希望在您的两种方法中都不要显式抛出异常。我想说,没有什么不好的,如果你的方法返回 null,如果它无法通过 id 找到对象。而RetrieveByStatus 方法可以返回一个空集合,而不是 null。

    除了您可以遵循 LINQ 中使用的模式之外,您还可以使用 Enumerable.FirstEnumerable.FirstOrDefault 方法(抛出异常或返回 null),因此您可以在特定情况下使用适当的方法,当id 100% 有效,否则可能会丢失。虽然返回元素序列的方法如果要返回的序列看起来是空的,则不会抛出异常;考虑Enumerable.Where

    【讨论】:

    • 感谢漂亮的链接和解释。在阅读了所有的 cmets 之后,我更倾向于在第一种情况下提出异常,在第二种情况下提出空列表。
    【解决方案4】:

    我更愿意在第一种情况下返回 nullempty list 第二种情况。

    但是如果你想引发异常,那么你可以为public Order RetrieveById(int id) 引发异常,因为这意味着id 无效,因为调用第一个方法意味着你知道id 并且它需要在那里。

    在第二种情况下,OrderStatus 可能是有效的,并且没有找到针对它的记录,因此返回一个空列表是个好主意。

    【讨论】:

      猜你喜欢
      • 2012-12-22
      • 2012-06-08
      • 1970-01-01
      • 1970-01-01
      • 2014-02-10
      • 1970-01-01
      • 2012-03-22
      • 2011-05-23
      • 1970-01-01
      相关资源
      最近更新 更多