Recurse.se Yada yada on Software Development

4Jul/170

Empty if null – Preventing null infections

In OO-style development, the value null causes endless issues. In FP-style development null is a much smaller problem, because using null isn't ideomatic style. In FP, instead of using null to indicate absence, lists tend to be empty, and optional values tend to use Option (a.k.a Maybe) types.

In one of our C# codebases, which is predominantly OO, using FP-style list processing often runs into the null problem.

Code like:

var currencies = contract.sections.Select(s => s.currency).Distinct();

raises exceptions if 'sections' is null, and constantly guaranteeing that all properties we use list operations on isn't null is a pain and breaks the chain of list processing.

We could have used the null conditional operator (?.) and written:

var currencies = contract.sections?.Select(s => s.currency).Distinct();

but this just propagates the the null value, spreading the null-infection downstream! Now currencies is either a list of currencies, or null.

Enter one of the most useful extension methods I've come up with, EmptyIfNull;

public static class EnumerableExtensions
{
  public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> items)
  {
    return items ?? Enumerable.Empty<T>();
  }
}

Now we can write:

var currencies = contract.sections.EmptyIfNull().Select(s => s.currency).Distinct();

which won't raise an exception even if 'sections' is null, allowing the code to flow more naturally, and we are also guaranteed that currencies is always a list (though maybe empty) but never null.