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


当前回答

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

其他回答

I call it my billion-dollar mistake…At that time, I was designing the first comprehensive type system for references in an object-oriented language. My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn’t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years. – Tony Hoare, inventor of ALGOL W.

See here for an elaborate shit storm about null in general. I do not agree with the statement that undefined is another null, but it is still worth reading. And it explains, why you should avoid null at all and not just in the case you have asked. The essence is, that null is in any language a special case. You have to think about null as an exception. undefined is different in that way, that code dealing with undefined behavior is in most cases just a bug. C and most other languages have also undefined behavior but most of them have no identifier for that in the language.

空的对消费者更友好。

有一个明确的方法来创建一个空的枚举:

Enumerable.Empty<Element>()

我喜欢在这里用适当的例子来解释。

考虑一个案例。

int totalValue = MySession.ListCustomerAccounts()
                          .FindAll(ac => ac.AccountHead.AccountHeadID 
                                         == accountHead.AccountHeadID)
                          .Sum(account => account.AccountValue);

这里考虑我使用的函数..

1. ListCustomerAccounts() // User Defined
2. FindAll()              // Pre-defined Library Function

我可以很容易地使用ListCustomerAccount和FindAll代替。

int totalValue = 0; 
List<CustomerAccounts> custAccounts = ListCustomerAccounts();
if(custAccounts !=null ){
  List<CustomerAccounts> custAccountsFiltered = 
        custAccounts.FindAll(ac => ac.AccountHead.AccountHeadID 
                                   == accountHead.AccountHeadID );
   if(custAccountsFiltered != null)
      totalValue = custAccountsFiltered.Sum(account => 
                                            account.AccountValue).ToString();
}

注意:由于AccountValue不为空,Sum()函数不会为空 返回null。因此我可以直接使用它。

空集合。如果您正在使用c#,那么假定最大化系统资源并不是必要的。虽然效率较低,但返回Empty Collection对于所涉及的程序员来说要方便得多(出于Will在上面概述的原因)。

Go似乎是首选nil而不是空数组的一种语言。

https://github.com/golang/go/wiki/CodeReviewComments#declaring-empty-slices

当声明一个空切片时,优先使用var t []string而不是t:= []string{}。前者声明一个nil切片值,而后者非nil但长度为0。它们在功能上是等价的——它们的len和cap都是0——但是nil片是首选样式。