简体   繁体   English

返回null或空集合会更好吗?

[英]Is it better to return null or an empty collection?

Suppose I have a method that returns an array or list or some other collection. 假设我有一个返回数组或列表或其他集合的方法。 If something goes wrong inside or when there is simply no data to return, what is better - to return null or to return array (list, etc.) that has length (count) equal to 0? 如果内部出现问题或者根本没有数据要返回,那么更好的方法是返回null或返回长度(计数)等于0的数组(列表等)?

In fact is it important, or it is just a matter of developer's preferences? 事实上它很重要,还是仅仅是开发人员的偏好?

It's better to return an empty collection. 最好返回一个空集合。 This way when someone calls the function like so: 这样当有人像这样调用函数时:

foreach(var i in items)
{

}

it doesn't throw a null reference exception on them. 它不会对它们抛出空引用异常。

Technically, you could argue empty vs. null means, but in reality a lot of people (myself included at times) forget to be defensive and don't check to see if the object is null before using it. 从技术上讲,你可以争论空与null意思,但实际上很多人(有时包括我自己)忘记防守,并且在使用之前不检查对象是否为空。 It's playing into what other people assume is going to happen, which means less bugs and less angry users. 它正在发挥其他人认为会发生的事情,这意味着更少的错误和更少愤怒的用户。

Your iteration code will be a lot easier if you return empty collections instead of null. 如果返回空集合而不是null,则迭代代码将更容易。

However, it may be important to distinguish between an empty collection and no collection of data, so it depends on the semantic of the actual type. 但是,区分空集合和不集合数据可能很重要,因此它取决于实际类型的语义。

If something "goes wrong" you should throw an exception. 如果出现“出错”,你应该抛出异常。 If there is no data to return, return an empty collection. 如果没有要返回的数据,则返回空集合。 Developers generally should not be surprised with a NullReferenceException when they ask for a list of items and there just happen to be none to return. 开发人员一般不应该对NullReferenceException感到惊讶,因为他们要求提供项目列表,而恰好没有人返回。

Here is an article by Josh Bloch explaining the same. 这是Josh Bloch的一篇文章,解释了同样的问题。 It's written in Java's context but it should apply to C# equally well. 它是用Java编写的,但它应该同样适用于C#。 Return zero-length arrays, not nulls 返回零长度数组,而不是空值

I could see this going either way. 我可以看到这种方式。 Ultimately an array or collection with have a larger footprint, but is "Safer" in the sense that if the result is being used in future foreach/iterations the result will skip over the code block and not end up with a null object exception. 最终是一个具有更大占用空间的数组或集合,但在某种意义上是“更安全”,如果结果将在未来的foreach /迭代中使用,结果将跳过代码块而不会以空对象异常结束。

Well, null and empty have two different meanings. 好吧, nullempty有两个不同的含义。 An empty collection effectively means "nothing is here", and could be valid. 空集合实际上意味着“什么都不在这里”,并且可能是有效的。 How would you know if something went wrong based on an empty collection? 你怎么知道基于空集合出了什么问题?

While it is safer for the calling method, that doesn't make it better than returning null. 虽然调用方法更安全,但这并不比返回null更好。 Good practice states you should check for null before doing operations on an object. 良好实践规定,在对对象执行操作之前,应检查null。 It is cheap anyway. 反正它很便宜。

If something truly went wrong, why cant you throw an exception? 如果出现了什么问题,为什么你不能抛出异常?

It is developer's preference really. 这真的是开发者的偏好。

Returning an empty list 返回一个空列表

Normally I'd return an empty list so that the receiver of the method's return object doesn't need to check for null and avoid any possible NullReferenceException . 通常我会返回一个空列表,以便方法的返回对象的接收者不需要检查null并避免任何可能的NullReferenceException

So anyone that expects a list can iterate through the list even though the list is empty (that will be a very quick for-each loop). 因此,任何需要列表的人都可以遍历列表,即使列表为空(这将是一个非常快速的每个循环)。

Returning null 返回null

If you are in an environment where running out of memory is a large issue you could optimize to return null value instead. 如果您处于内存不足的大环境中,则可以优化以返回空值。 However that means that everyone that uses the method in question always need to check for null and doesn't solve the problem of possible memory leaks. 但是,这意味着使用该方法的每个人总是需要检查null并且不能解决可能的内存泄漏问题。

If something goes wrong then you shouldn't be returning anything, rather throwing an exception. 如果出现问题,那么你不应该返回任何东西,而是抛出异常。

You need to agree a consistent approach for the project as to the meaning of NULL and {} and stick to it. 对于NULL和{}的含义,您需要就项目的一致方法达成一致并坚持下去。 Either you are going to use NULL or not, if you are everyone needs to know to check. 如果您是每个人都需要知道检查,您要么使用NULL,要么不使用NULL。

I like to think of NULL - not tried to or see if there is anything, there might be some but who knows. 我喜欢想到NULL - 没有试过或者看看是否有什么,可能有一些但是谁知道。

Empty collection - tried to populate and as far as the system is concerned there are no items, which is quite a strong statement. 空集合 - 试图填充,就系统而言,没有项目,这是一个非常强烈的声明。

eg Wallet.Notes collection. 例如Wallet.Notes集合。

  • NULL - I haven't opened my wallet, so I don't know if I have any notes in it. NULL - 我没有打开我的钱包,所以我不知道我的钱包里有没有。
  • List={} - I've checked and I definitely don't have any notes cos I spent it all on beer. List = {} - 我已经检查了,我绝对没有任何笔记,因为我把所有这些都花在了啤酒上。

Although I'd say it's mostly a matter of developer's preference, to return an empty collection might be a better approach. 虽然我说这主要取决于开发人员的偏好,但返回空集合可能是一种更好的方法。

Let's say you have an object which contains a collection member. 假设您有一个包含集合成员的对象。

public class Customer {
    private IList<Order> _orders;

    public Customer() {
        _orders = new List<Order>();
    }

    public IList<Order> Orders {
        get {
            return _orders;
        } 
    }
}

One generally will prefer to have this member as a readonly property so that its customer's orders don't get lost without any apparent reason. 人们通常希望将此成员作为只读属性,以便其客户的订单不会在没有任何明显原因的情况下丢失。 So, returning null is not an option. 因此,返回null不是一个选项。 You would likely work better with an empty collection than a null reference. 使用空集合而不是空引用可能会更好。 As such, instantiating the collection within the class constructor is a better approach. 因此,在类构造函数中实例化集合是一​​种更好的方法。

And most importantly, when using DataBinding, for instance, you might get strange behaviour when returning null collection reference, as it will best work with an empty collection instead. 最重要的是,例如,在使用DataBinding时,在返回null集合引用时可能会出现奇怪的行为,因为它最好使用空集合。

Another example, when iterating through a collection such as: 另一个例子,当迭代集合时,例如:

foreach (Order o in c.Orders) {
    // Do something here...
}

This foreach loop will simply not get executed when the collection is empty, without you having to check whether it is a null reference first. 当集合为空时,不会执行此foreach循环,而不必先检查它是否为空引用。 It simplifies the code and minimizes its complexity. 它简化了代码并最大限度地降低了复杂性。

This depends on the scenario you're wokring in. 这取决于您所处的情景。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM