当列表为空时,是应该返回空的List<T>还是null?

7

当我有一个返回对象集合的方法,如果对象数量为零,我应该返回什么?null还是只是空的List<T>?哪种做法更好?

public List<string> GetPupilsByClass(string className)
{
     ....
}

最好在 Code Review SE 进行实践回顾。 - Grant Thomas
1
@Mr. Disappointment:我认为这个问题似乎足够一般化,适合在 Stack Overflow 上提问。 - BoltClock
@BoltClock 这就是为什么我没有标记它的原因。但是在那里更加合适。 - Grant Thomas
可能是重复的问题:函数应该返回null还是一个空对象? - H H
9个回答

15

我肯定会返回一个空列表,这样就可以在调用对象时无需进行null检查。返回空列表和不返回任何内容是有区别的,因此调用代码可能并不希望接收到空引用(除非发生异常或其他情况)。


3

要看具体情况而定,但通常情况下,返回一个空列表会更加典型,否则调用者必须知道进行null检查。我会返回null的主要情况是,如果这是一个以下风格的方法:

bool Try*(args, out result)

调用者期望(在收到false时)甚至不查看result的值。

如果你要返回数组,有一个好办法——可以在某个静态字段中存储一个零长度的类型化数组,并返回它。但是,最终分配一个空列表也不会占用太多资源,所以只需返回它即可。


3
作为调用者,我希望得到一个空列表。如果返回null,则表示“概念列表”未定义,就像数据库中的null一样。
此外,始终返回空集合而不是null,这样像这样的客户端将永远不会失败:
foreach(var element in obj.Method()) ...

3
根据Microsoft的说法,从字段或属性中返回null字符串或数组是不允许的。我认为这个规则也应该适用于方法(可能出现在我没有发现的某些地方)。
关于返回空数组:
字符串和数组属性不应返回null引用。在这种情况下,null很难理解。
一般规则是,null、空字符串("")和空(0项)数组应该被视为同样的方式处理。应返回空数组而不是null引用。 MSDN参考资料

1
更好的做法是返回`IEnumerable`。在方法内使用`yield return`和`yield break`来构建集合。通过这种方式,你可以推迟数组的创建。点击这里获取更多信息。你会发现`IEnumerable`有一个好处,它可以在扩展方法和linq查询中链接:
var results = from x in GetPupilsByClass(className) where x.StartsWith("A");

如果你一定要返回一个完整的列表(由于yield的惰性特性),那么我建议将你的方法签名更改为以下形式:
public bool TryGetPupilsByClass(string className, out ICollection<string> pupils)

这种技术有三个优点。

  1. 你的意图很清楚 -- 如果返回值为true,那么pupils将被初始化。你的代码使用者不必猜测你已经采取了哪种做法。
  2. 如果集合为空,你当然不会费心分配一个列表,这样可以节省内存分配。
  3. ICollection<string>是强类型的,而不会暴露你正在使用的存储机制。应该谨慎使用返回具体类的方法。替代方案包括IList<string>ReadOnlyCollection<string>IEnumerable<string>等,但你选择的方法肯定会让用户对结果的可操作性有更清晰的认识。

1

这个方法是IFC方法吗?也就是说,它被外部对象使用而不受您控制? 如果答案是肯定的,那么我会返回一个空集合,因为调用者不希望出现异常。

如果这个方法是内部方法,只有您自己使用,那么我会返回null,以节省为空集合分配的浪费内存和一旦停止使用后GC性能的影响。


1

始终返回空列表。这样你就可以避免最常见的异常 - NullReferenceException


0

我通常遵循R.Martin的Clean Code指南。建议返回一个空列表:

public List GetPupilsByClass(string className) { .... }

我这样做有以下原因:

  1. 调用方法不必检查null。
  2. 此方法不必进行错误处理。
  3. 异常将在更高级别的方法中捕获。

0

这实际上取决于您的代码在哪个上下文中使用。对于大多数情况,我会返回一个零对象列表,并且我认为在这里也最好这样做 - 这更符合您正常结果的一致性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接