c# c#队列 - 返回null还是空集合更好?




9 Answers

空集合。 总是。

这很糟糕:

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

在返回集合或枚举时,不要返回null ,这被认为是最佳实践。 总是返回一个空的枚举/集合。 它可以防止前面提到的废话,并且可以防止您的汽车受到同班同学和您班级用户的怂恿。

在谈论物业时,请务必设置一次物业并忘记物业

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>()可以看作比返回效率更高,例如,新的空集合或数组。

c#栈 list

这是一个普遍的问题(但我正在使用C#),什么是最好的方法(最佳实践),你是否返回null或空收集的方法有一个集合作为返回类型?




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

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

一些具体的例子:

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



空对消费者更友好。

有一个明确的方法来组成一个空的枚举:

Enumerable.Empty<Element>()



如果一个空集合在语义上是有意义的,那就是我喜欢返回的东西。 为GetMessagesInMyInbox()返回一个空集合会传达“你的收件箱中确实没有任何消息”,而返回null可能对传达没有足够的数据来说明可能返回的列表应该是什么样子很有用。




有人可能会争辩说, 空对象模式背后的推理类似于赞成返回空集合的推理。




我会争辩说null与空集合不同,你应该选择哪一个最能代表你要返回的东西。 在大多数情况下, null不是什么(SQL除外)。 一个空的集合是一些东西,虽然是空的东西。

如果你必须选择一个或另一个,我会说你应该倾向于一个空集合而不是空集合。 但有时候,空集合与空值不同。




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

考虑一个案例..

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

我可以轻松使用ListCustomerAccountFindAll而不是。,

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不为null ,Sum()函数将不会返回null ,因此我可以直接使用它。




空集合。 如果您使用C#,则假设是最大化系统资源不是必需的。 尽管效率较低,但返回空集合对于程序员来说更为方便(因为上面会列出)。




我称之为数十亿美元的错误......当时,我正在设计面向对象语言的第一个综合类型系统。 我的目标是确保所有引用的使用都绝对安全,编译器会自动执行检查。 但我无法抗拒放入空引用的诱惑,因为它很容易实现。 这导致了无数的错误,漏洞和系统崩溃,这可能在过去的四十年中造成了数十亿美元的痛苦和损害。 - ALGOL W的发明人Tony Hoare

一般来说,请看here精心制作的关于null垃圾风暴。 我不同意这种说法,即undefined是另一个null ,但仍值得阅读。 它解释说,为什么你应该避免null ,而不只是在你问的情况下。 其实质是, null在任何语言中都是特例。 你必须考虑null作为例外。 undefined方式不同,处理未定义行为的代码在大多数情况下只是一个错误。 C和大多数其他语言也有未定义的行为,但其中大多数语言中没有标识符。




Related