2

Let's say I have a function like this:

public List<int> func()
{}

Now, for some reason I don't have anything to put into the list, so I will just be returning "something empty". According to a good practice, which one of the following three should I return in the function above?

return null;
return new List<int>();  
return default(List<int>);  //Is this the same thing as the one above?
user3595338
  • 737
  • 3
  • 11
  • 26
  • 2
    First of all, don't return `List` in public methods, otherwise you'll regret later. Prefer `IEnumerable`. – Sriram Sakthivel Aug 10 '14 at 08:27
  • Sriram Sakthivel: Why? – user3595338 Aug 10 '14 at 08:28
  • Later at sometime if you wanted to change the internal implementation to use some other datastructure(say `HashSet`) you need to modify all the code base which uses it. If you're using `IEnumerable` everything will work fine. – Sriram Sakthivel Aug 10 '14 at 08:30
  • I voted to reopen this question. Although it has a big overlap with the mentioned question, the part about `default(List)` is new to the mix. – Emond Aug 10 '14 at 08:32
  • A link to a famous bit of trivia about nulls: http://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions – hyde Aug 10 '14 at 08:34
  • @ErnodeWeerd I don't think this should have reopened. If not a duplicate it is opinion based. In fact I voted for opinion based only. – Sriram Sakthivel Aug 10 '14 at 08:34
  • @SriramSakthivel I would prefer `IList` over `IEnumerable`. Then you don't sacrifice functionality (indexing). You still keep a great deal of flexibility. Even arrays derive from `IList` in C#. – metacubed Aug 10 '14 at 08:38
  • @SriramSakthivel: On the other hand, if you're using `IEnumerable` then callers can't use anything specific to `IList` or `List`. There's a balance here, and it's not always as clear-cut as you're implying. In particular, for private or internal methods it's relatively easy to change the return value later, so you can be a bit more liberal. – Jon Skeet Aug 10 '14 at 08:39
  • @JonSkeet True, that's why I said *don't return `List` in public methods*, If private or internal you can have whatever you want. Also it really depends upon what caller needs to do, If they just needs to iterate `IEnumerable` otherwise, `IList` will be good. That's also arguable when caller calls `list.Add` and you wanted to be aware of any adding of elements? If that needs to be readonly access `ReadOnlyCollection` can be good choice. – Sriram Sakthivel Aug 10 '14 at 08:44
  • @SriramSakthivel: Fair, I'd not spotted the public part. But again, it depends on context. For example, a `ToList` method is entirely justified in returning a `List` :) If you don't want the caller to be modifying the list, you shouldn't return a `List` even as an `IEnumerable`, as the caller can cast. And don't forget that you don't always know what the caller needs to do for public methods... – Jon Skeet Aug 10 '14 at 08:45
  • @metacubed That really depends. Assume you return array(which is `IList`) if the caller calls `list.Add` it will blow up in runtime with exception. I'd not expect that. Do you? Also if you need the control over add/removing elements then returning `IList` is not a good choice as user can add anything he want you'll not be notified. – Sriram Sakthivel Aug 10 '14 at 08:49
  • @JonSkeet Yes, as you said caller can cast and take the `List` later he's going to suffer when internal implementation happens to use different datastructure. You're not going to have trouble that time, because it is his mistake that he depends on the internal implementation detail. As for *you don't always know what the caller needs to do for public methods* : Agreed :) – Sriram Sakthivel Aug 10 '14 at 08:53
  • @SriramSakthivel: It's not just if the implementation changes - my point is that if you return a mutable data structure to the caller, they can change it. If you don't want them to be able to change it, don't return that. Use `ReadOnlyCollection` instead. – Jon Skeet Aug 10 '14 at 11:21

4 Answers4

7

Return an empty list:

return new List<int>();

The default(List<int>) will return null; not an empty list!

Returning an empty list prevents excessive null checking after each call to your function. See Is it better to return null or empty collection?

Community
  • 1
  • 1
Emond
  • 50,210
  • 11
  • 84
  • 115
  • Is it also a good practice to return a empty object when the expected function output is not a collection but a object of a certain class? – blondelg Nov 15 '20 at 13:09
  • 1
    @blondelg - No, because there is no common understanding of what an empty object is/means. This is what , in general, null is used for. – Emond Nov 15 '20 at 13:21
3

Return an empty list. When you return null, you have to check that condition in the code that called func.

Oswald
  • 31,254
  • 3
  • 43
  • 68
3

It really depends; for example if for some reason you don't have any items perhaps you should be throwing an exception rather than returning anything?

If the return type being empty is acceptable then personally I would suggest using the null object pattern.

In any case perhaps the most important factor is what your other code does in similar situations. i.e. consistency is a major factor. So - if you return empty objects in other places then do that. If you return null, then do that.

Fraser
  • 15,275
  • 8
  • 53
  • 104
1

I would say:

    return Enumerable.Empty<int>();
martenolofsson
  • 501
  • 1
  • 4
  • 20