这是一个一般性的问题(但我使用c#),最好的方法(最佳实践)是什么,对于一个有集合作为返回类型的方法,你返回null集合还是空集合?


当前回答

有人可能会说,空对象模式背后的原因与支持返回空集合的原因类似。

其他回答

这取决于你的合同和具体情况。 通常最好返回空集合,但有时(很少):

Null可能意味着更具体的东西; 你的API(合约)可能会强制你返回null。

一些具体的例子:

一个UI组件(来自一个不受你控制的库),如果传递一个空集合,可能会呈现一个空表,或者如果传递null,则根本不呈现表。 在Object-to-XML (JSON/其他)中,null表示元素缺失,而空集合将呈现冗余(可能不正确)<collection /> 你正在使用或实现一个明确声明null应该返回/传递的API

空集合。总是这样。

这糟透了:

if(myInstance.CollectionProperty != null)
{
  foreach(var item in myInstance.CollectionProperty)
    /* arrgh */
}

在返回集合或枚举对象时,NEVER返回null被认为是最佳实践。ALWAYS返回一个空的可枚举/集合。它可以防止前面提到的废话,并防止你的车被同事和你的类的用户怂恿。

在谈论属性时,总是设置一次属性,然后忘记它

public List<Foo> Foos {public get; private set;}

public Bar() { Foos = new List<Foo>(); }

在.NET 4.6.1中,你可以将这些内容进行大量压缩:

public List<Foo> Foos { get; } = new List<Foo>();

当谈论返回枚举对象的方法时,你可以很容易地返回一个空的枚举对象而不是null…

public IEnumerable<Foo> GetMyFoos()
{
  return InnerGetFoos() ?? Enumerable.Empty<Foo>();
}

使用Enumerable.Empty<T>()可以被视为比返回一个新的空集合或数组更有效。

从管理复杂性(一个主要的软件工程目标)的角度来看,我们希望避免将不必要的圈复杂性传播到API的客户端。向客户端返回null就像返回另一个代码分支的圈复杂度成本。

(这对应于单元测试负担。除了空集合返回情况外,您还需要为空返回情况编写一个测试。)

总是为你的客户端着想(他们正在使用你的api):

返回'null'通常会导致客户端不能正确处理null检查的问题,这会导致运行时出现NullPointerException异常。我曾经见过这样的情况,缺少空检查会导致优先级生产问题(客户端对空值使用foreach(…))。在测试期间,问题没有发生,因为所操作的数据略有不同。

框架设计指引第二版(第256页):

不返回空值从 集合属性或方法 返回集合。返回空 集合或空数组。

这是另一篇关于不返回null的好处的有趣文章(我试图在Brad Abram的博客上找到一些东西,他链接到了这篇文章)。

编辑-正如Eric Lippert现在对原始问题的评论,我也想链接到他的优秀文章。