Should Functions Return Null or an Empty Object

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 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.

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 {}.

SHOULD function return Null or Object of it?

I think it's better to return an empty list. That way you don't need to check if it is null on the other side and you can directly iterate over it.

Also, that's how it works when you use Entity Framework. You run a query and if there are no results you get an empty collection. I'm pointing this out as an example and also for consistency.

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;
}

null objects vs. empty objects

I tend to be dubious of code with lots of NULLs, and try to refactor them away where possible with exceptions, empty collections, Java Optionals, and so on.

The "Introduce Null Object" pattern in Martin Fowler's Refactoring (page 260) may also be helpful. A Null Object responds to all the methods a real object would, but in a way that "does the right thing". So rather than always check an Order to see if order.getDiscountPolicy() is NULL, make sure the Order has a NullDiscountPolicy in these cases. This streamlines the control logic.



Related Topics



Leave a reply



Submit