Is It Better to Return Null or Empty Collection

Is it better to return null or empty collection?

Empty collection. Always.

This sucks:

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

It is considered a best practice to NEVER return null when returning a collection or enumerable. ALWAYS return an empty enumerable/collection. It prevents the aforementioned nonsense, and prevents your car getting egged by co-workers and users of your classes.

When talking about properties, always set your property once and forget it

public List<Foo> Foos {public get; private set;}

public Bar() { Foos = new List<Foo>(); }

In .NET 4.6.1, you can condense this quite a lot:

public List<Foo> Foos { get; } = new List<Foo>();

When talking about methods that return enumerables, you can easily return an empty enumerable instead of null...

public IEnumerable<Foo> GetMyFoos()
{
return InnerGetFoos() ?? Enumerable.Empty<Foo>();
}

Using Enumerable.Empty<T>() can be seen as more efficient than returning, for example, a new empty collection or array.

Is it better to return null or an empty collection?

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. It's playing into what other people assume is going to happen, which means less bugs and less angry users.

Why is it considered good practice to return an empty collection?

If you return an empty collection (but not necessarily Collections.emptyList()), you avoid surprising downstream consumers of this method with an unintentional NPE.

This is preferable to returning null because:

  • The consumer doesn't have to guard against it
  • The consumer can operate on the collection irrespective of how many elements are in it

I say not necessarily Collections.emptyList() since, as you point out, you're trading one runtime exception for another in that adding to this list will be unsupported and once again surprise the consumer.

The most ideal solution to this: eager initialization of the field.

private List<String> bone = new ArrayList<>();

The next solution to this: make it return an Optional and do something in case it doesn't exist. Instead of throwing you could also provide the empty collection here if you so desired.

Dog dog = new Dog();
dog.get().orElseThrow(new IllegalStateException("Dog has no bones??"));

Is it better to return an empty task or null? c#


if it finds no results is it better to return an empty task or null?

There's a couple things to consider here:

First, you should never return a null Task. In the async world, a null task just doesn't make sense. Task represents the execution of the asynchronous method, so for an asynchronous method to return a null task is like telling the calling code "you didn't really just call this method" when of course it did.

So, a Task/Task<T> returned from a method should never, ever be null. However, you still have the option of returning a null value inside a regular task. That is up to you.

with tasks i am unsure which is best.

The task is just a wrapper. The underlying logic is still the same. Think of how this method would look if it were synchronous; would your return type be int and return 0 if nothing was found, or would your return type be int? and return null if nothing was found? After making that choice for a synchronous method, then wrap it in Task<T> for the asynchronous method.

As a final note, I must say:

  • Do not ever, ever use the Task constructor.
  • Avoid Task<T>.Result; use await instead.
  • Do not use ContinueWith; use await instead.

Your method can be drastically simplified:

public virtual async Task<int> GetJobRunIdAsync(int jobId)
{
var jobMonRequest = ...;
var jobMonResponse = await Client.jobmonAsync(jobMonRequest);
if (jobMonResponse == null)
return 0;
if (jobMonResponse.jobrun.Length > 1)
throw new Exception("More than one job found, Wizards are abound.");
return jobMonResponse.jobrun.Single().id;
}

Or, if you want to return a value (not task) of null:

public virtual async Task<int?> GetJobRunIdAsync(int jobId)
{
var jobMonRequest = ...;
var jobMonResponse = await Client.jobmonAsync(jobMonRequest);
if (jobMonResponse == null)
return null;
if (jobMonResponse.jobrun.Length > 1)
throw new Exception("More than one job found, Wizards are abound.");
return jobMonResponse.jobrun.Single().id;
}

Should I return a null or an empty list?

I'd be inclined to return an empty list.

At the conceptual level, null represents unknown. In your case, the orders associated with the customer are not unknown; rather, there are no orders. An empty list represents this precisely while null is imprecise and could be ambiguous--does "null" orders mean no orders or simply that the orders property hasn't yet been populated?

At the practical level, by returning an empty list, code that does computations on orders will probably need less corner-case checking. For example, a method that uses foreach to iterate through the list of orders should work just fine with a zero-length orders list (no iteration will occur) while using null for no orders will require that the method have a safety check.

Should functions return null or an empty object?

Returning null is usually the best idea if you intend to indicate that no data is available.

An empty object implies data has been returned, whereas returning null clearly indicates that nothing has been returned.

Additionally, returning a null will result in a null exception if you attempt to access members in the object, which can be useful for highlighting buggy code - attempting to access a member of nothing makes no sense. Accessing members of an empty object will not fail meaning bugs can go undiscovered.

Is it good or bad practice to design your code to treat an empty collection and a null value differently?

In his (very good) book Effective Java, Joshua Bloch treats this question for the returned values of methods (not "in general" like your question) :

(About use of null) It is errorprone, because the programmer writing
the client might forget to write the special case code to handle a null
return.

(...)

It is sometimes argued that a null return value is preferable to an
empty array because it avoids the expense of allocating the array.
This argument fails on two counts. First, it is inadvisable to worry
about performance at this level unless profiling has shown that the
method in question is a real contributor to performance problems (Item
55). Second, it is possible to return the same zero-length array from every invocation that returns no items because
zero-length arrays are immutable and immutable objects may be shared
freely (Item 15).

(...)

In summary, there is no reason ever to return null from an
array- or collection-valued method instead of returning an empty array
or collection.
(...)

Personnally I use this reasoning as a rule of thumb with any use of Collections in my code. Of course, there is some case where a distinction between null and empty makes sense but in my experience it's quite rare.

Nevertheless, as stated by BionicCode in the comments section, in the case of a method that returns null instead of empty to specify that something went wrong, you always have the possibility of throwing an exception instead.

Should I return null, an empty object or an empty array for json with no data?

The differences are pretty negligible.

null is the usual way to denote "no value", but your client side code will need to explicitly check for that.

If the response actually means "here are the results, but they're empty", [] or {} might be more suitable, as long as you match the format of non-empty responses (i.e. if the client is expecting an array, don't send {}, and vice versa).

Basically:

  • If an empty result set is a special case and you want to write explicit behavior for it, null seems more appropriate.
  • If your client expects an array (e.g. it will loop through the results), then use [].
  • If your client expects a map of key-value pairs (e.g. it will loop through keys or will use result[someKey]), then use {}.
  • If your client expects a single object (i.e. it expects the result to have well-known properties and will do something like result.someProperty), then null is better than returning an empty object.

Or more clearly: If the client thinks of the result as a single value, use null. If the client thinks of it as a list, use []. If the client thinks of it as a map, use {}.

Empty collection vs null return? How big is the memory usage drawback?

Return a static, immutable empty list instead of a new object. That way, all empty lists refer to the same static object. For example:

  • Collections.emptyList()
  • List.of() (Java 9 and later)


Related Topics



Leave a reply



Submit