LINQ and iterating over null collections.

Ok, todays title is weird, but I have come up with a little hack, that will make the code easier to read (sometimes).

At work we have some pretty clear specifications, that says how to fill out some properties in an object that is to be sent over a web service. The specification could go something like (this is fictive – we don’t do webshops at work):

Accounting
– Month total amount WebShop:Orders:Amount:Sum
– Month total items number of items in WebShop:Orders
– Month average sales price Month total amount / Month total items,
If Month total items is zero then don’t set this field.

In code this translates to something like:

var accounting = new Accounting();
accounting.MonthTotalAmount = WebShop.Orders.Sum(o => o.Amount);
accounting.MonthTotalItems = WebShop.Orders.Count();
if(accounting.MonthTotalItems != null)
  accounting.MonthAverageSalesPrice = accounting.MonthTotalAmount / 
                                      accounting.MonthTotalItems ;

This is pretty straight forward. As it happens some of these specifications are very long with 50+ pages with 100+ different properties to read from. All of this is of corse split into smaller classes, but that is irrelevant for the topic at hand. It also happens that some of the properties will return null instead of an empty collection – this is unfortunately not consistent throughout our code base. This means that I have to check for null, for each property, that I want to set:

if(WebShop.Orders != null)
  accounting.MonthTotalAmount = WebShop.Orders.Sum(o => o.Amount);
else
  accounting.MonthTotalAmount = 0m;

This becomes  quite boring to write, and it also makes it more difficult to read and compare to the specification. It would be nice if the Sum(o => o.Amount) of null was 0. In order to do exactly that I made an extension method called NullToEmpty(), that will return the collection if it is not null, and an empty collection if it is null.

For example I can write

accounting.MonthTotalAmount = WebShop.Orders.NullToEmpty().Sum(o => o.Amount);

and it will work no matter if Orders is null or not null.

The code for the method is inspired by some code I saw in the .Net framework (I don’t remember where).

public static class LinqExtension
{
  public static IEnumerable NullToEmpty(this IEnumerable source)
  {
    return source ?? EmptyEnumerable.Instance;
  }

  internal class EmptyEnumerable
  {
    static TElement[] instance;

    public static IEnumerable Instance
    {
      get { return instance ?? (instance = new TElement[0]); }
    }
  }
}

I don’t think this should be used blindly everywhere, but in my case it helps readability, and it is not used in highly performance critical situations.

Advertisements

About Lund

Owner of iCodeIT, a software consulting company. I am primarily working the .NET development and architecture.
This entry was posted in C#, Linq and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s