views:

1278

answers:

13

Suppose you have a method that should create and return an array of some sort. What if the array doesn't get populated. Do you return an empty array or null/nothing?

+2  A: 

I return an empty array - just seems like the right thing to do.

Patrick Harrington
+1  A: 

It really depends on what the caller wants to do with the result.

Usually I return the empty array (or Collection, in Java). That's because I'm usually going through a loop and optionally adding them to the Collection, and then returning it. Checking at the end if Collection.size() == 0 is an extra step. And then the caller needs to add an extra check to see if the result is 0 and if so, avoid iterating the Collection.

I appreciate it might be cleaner to return null, but it's easier not to unless I have a reason to.

Paul Tomblin
+24  A: 

In .NET it's better to return an empty array than null because it saves the caller having to write a null check and/or risking a NullReferenceException; you'll see this is a common pattern in the base class libraries. The only case in which you wouldn't do this is in the unlikely scenario that an empty array and null have different semantic meanings.

The official array usage guidelines state:

The general rule is that null, empty string (""), and empty (0 item) arrays should be treated the same way. Return an empty array instead of a null reference.

That said, if you're using .NET 2.0 or later, it's much better to return an IEnumerable<T> or one of its extensible derivatives such as Collection<T>, ReadOnlyCollection<T>, ICollection<T> or IList<T> (in which case I'd still tend to return an empty one instead of null). More info as to why these should be preferred can be found at Eric Lippert's blog.

Greg Beech
Actually, it's best to be as specific as possible in output types, and as loose as possible in input types. So take IEnumerable in, but return the array. Saves the caller the need to copy it to a new array or list just to be sure it has a copy of the data before going on.
Lasse V. Karlsen
@lassevk - Did you read the post I linked to? Returning an array is almost always the wrong choice.
Greg Beech
It depends, if you get those 100 calls he's talking about, in many times you're forcing the caller to build his own list, which basically means you funnel the original array or whatnot through a IEnumerable into a new list. It depends, there are no silver bullets.
Lasse V. Karlsen
And yes, I agree with the article too, but it all depends. I never return cached arrays for the very reasons he mentions, and yes, returning one of the Collection types is a good idea, but I see enough IEnumerable<T> return types for the wrong reasons too.
Lasse V. Karlsen
Indeed - you need to pick the appropriate type, and there are some cases in which returning an array (even the internal buffer) is the right thing to do. But I reckon that the safe option is not to return either an array or a List<T> until you understand when and why to break the rules.
Greg Beech
And when I said "most specific type", I did not mean "always return an array". If your code in the method builds up a new List<Int32>, then return that, it will be fresh and the caller can do what he wants with it. But I think we basically agree :)
Lasse V. Karlsen
+1  A: 

If this is truly language independent I would return an empty array object, most containers should have a function such as IsEmpty() so the caller of the function would check if the Array IsEmpty before they do anything with it.

If this is in C++ I can see it either going to null, or if you're passed in a reference to the array then you return the array size...

Lirik
A: 

Unless for some reason there is a differance in meaning in your code for a result being a null array verses a plain old blank one, I would return a blank one. This also might be a language specific thing. In some languages, you may only have one option.

Charles Graham
+2  A: 

Your answer to this question probably greatly depends which language you are working in. In languages like C, It's not possible to return an empty array, as an array is just a pointer to some memory address where the array begins. In this case, the only option is to return a null pointer.

Kibbee
A: 

I'd imagine this depends on the way that the language handles it.

In C, I pass pointers around and always include a pointer that is the size of the array. The calling function then has to provide two things: the array, and the size of the array. if the function doesn't populate the array, it just returns the same pointer back, and doesn't do anything to the array size. Usually i just re implement a vector type structure and work with that.

In perl, array size is handled implicitly, so i just return an empty array, or if an error, I modify the error code variable and return an undef.

In java, i use ArrayLists, and use the size property.

Ape-inago
+1  A: 

I return whatever the caller expects. If the function is supposed to return "all objects for which X is true", and X is not true for any objects, I return an empty array.

if the function was not even able to perform this search for "objects for which X is true", then it failed, and has to signal that back to the caller somehow. That could be done by returning null.

jalf
A: 

If you're lucky enough to be using C#, declare a static readonly property like this:

public static class ArrayUtil<TElement> 
{
    public static readonly Empty = new TElement[0];
}

(Is this in the BCL? Why not?)

You can now return ArrayUtil<int>.Empty or whatever. This pretty much eliminates the runtime costs of using empty array instead of null and gives the caller a simpler time than having to deal with nulls.

Daniel Earwicker
System.Linq.Enumerable.Empty<T>().ToArray() , but this doesn't eliminate the runtime cost you mention.
David B
A: 

The answer depends on the contract between the caller and the function. If you intend to flag the array as not being valid, then null is a better way to do it than returning a zero-size array, since a zero-size array could be a valid result in some situation.

Jin Kim
A: 

Well, it really depends about the semantic you want to give to your return.

Usually, I use pre and post conditions for nearly all my functions/methods. That means that if my method is supposed to return an array with data from a particular treatment, if this treatment fails, the object should be null and the post condition would fail.

But in your case, I assume you don't use DbC, so, if I refer only to your question:

What if the array doesn't get populated.

Then I would return null, as I supposed that someting went wrong in your phrasing.

gizmo
+2  A: 

If you read your question closely, you will realize that you have actually already answered it yourself: you wrote "a method that should create and return an array of some sort" and not "a method that should create and maybe return an array of some sort or not".

Really, it depends on the specification. But with the way you phrased it, there's no way the method can return null. Which is the style I would prefer anyway, it just makes edge-case handling so much easier.

Jörg W Mittag
A: 

I agree with Greg B, the way I do it is to return a empty array, or any object for that matter. I ususaly try to have a default value so that I can check that. If I can't use adefault value, because that could mean something, like in the case of int's I set the it to be Nullable int? i = null. Then I can use the GetValueOrDefault method, var result = i.GetValueOrDefault().

Gargamel