何时引发exception或返回null?

我在数据访问层上有一些function

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

现在我对exception提升有点困惑。

在RetrieveById函数的情况下,小于1的id是无效的id,因此我想提出exception。 我想为数据库中不存在的Id返回null。 然后感觉就像我过度复杂。

对于RetrieveByStatus,我觉得当数据库中没有该状态的数据时返回一个空列表。

但是我已经看到有些人在RetrieveById无法返回任何内容时引发exception但是当没有记录时它应该不会引发exception或应该引发exception吗?

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

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

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

我宁愿在第一种情况下返回null ,在第二种情况下返回一个empty list

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

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

  1. 首先阅读MSDN: 创建和抛出exception(C#编程指南) 。 它列出了当您希望抛出exception时的两种情况,以及何时避免它。
  2. 还要考虑C#中try / catch的实际开销是多少?

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


至于我自己,我更喜欢你的两种方法都不要明确地抛出exception。 我会说,没有什么不好,如果你的方法返回null,如果它找不到id的对象。 而RetrieveByStatus方法可以返回空集合,而不是null。

除此之外,您可以遵循LINQ中使用的模式,例如Enumerable.First和Enumerable.FirstOrDefault方法(抛出exception或返回null),因此您可以在特定情况下使用适当的模式,当id为100%有效或相反,它可能会丢失。 虽然返回序列元素的方法在返回的序列似乎为空时不会抛出exception; 考虑Enumerable.Where 。

我希望尽可能避免返回null,因为NullRefExceptions比特定的exception(比如OrderNotFoundException更加神秘。 此外,当你不得不经常期望实体为空时,代码变得相当迟钝。 无论如何,这应该是一个例外情况 – 如果数据库中不存在该ID,您在哪里获得该ID?

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