Geeks With Blogs
Works on my machine

Have you ever had to write a code like this one?

var store = GetStore();
string postCode = null;

if (store != null && store.Address != null && store.Address.PostCode != null)
     postCode = store.Address.PostCode.ToString();

I’m sure you have. We’ve all been there.
The goal is to retrieve (or compute) a value, but in order to do that, we have to get through many intermediate objects, which could be in a default state. The aforementioned example is pretty easy. Sometimes, along the way, there are additional method calls, “as” conversions or collections. We have to handle properly each of them, which bloats further the code, making it less readable. There’s got to be a better way.


Conditional extensions

Many developers found a solution in conditional extensions. If you google “c# deep null check” you will find several implementations. Their names vary, but the idea behind them is the same:

public static TResult IfNotNull<TResult, TSource>(
    this TSource source,
    Func<TSource, TResult> onNotDefault)
    where TSource : class
    if (onNotDefault == null) throw new ArgumentNullException("onNotDefault");

    return source == null ? default(TResult) : onNotDefault(source);

As you can see, the extension returns a value of TResult type. The source object is required to obtain the result. If the former is null, we are unable to do that, thus the method returns default value of TResult type. If it’s not the case, we can safely invoke the onNotDefault delegate.
After adding IfNotNull extension to our project, the first example can be rewritten in the following way:

var postCode =
        .IfNotNull(x => x.Address)
        .IfNotNull(x => x.PostCode)
        .IfNotNull(x => x.ToString());

It really pays off in more complex scenarios, i.e. when we have to call some methods along the way and store the results in temporary variables.

The IfNotNull extension can be improved in several ways. I would like to focus on 2 of them:

  • The aforementioned extension deals only with reference types. We can amend it to work with value types too.
  • Have you thought about string type? It’s often not enough to ensure that a string variable is not null. We want to work with not empty (or even not whitespace only) strings.
    The same thing applies to collections. It’s not enough that it’s not null. It has to have at least one element in order to compute an average (or to get the biggest element).

To address these issues we can transform the IfNotNull extension into the following IfNotDefault extension:

public static TResult IfNotDefault<TResult, TSource>(
    this TSource source,
    Func<TSource, TResult> onNotDefault,
    Predicate<TSource> isNotDefault = null)
    if (onNotDefault == null) throw new ArgumentNullException("onNotDefault");

    var isDefault = isNotDefault == null
        ? EqualityComparer<TSource>.Default.Equals(source, default(TSource))
        : !isNotDefault(source);

   return isDefault ? default(TResult) : onNotDefault(source);

It’s not much different from the original implementation. I’ve got rid of the where TSource : class constraint to support structs. After doing that I could no longer use simple null equality comparison (because structs aren’t nullable) so I had to ask EqualityComparer<TSource>.Default to do the job.
And there is also optional predicate, if we’re not happy with the default comparison.

Let me show you a couple of usage examples:

1. Performing some operation on string if it’s not empty:

return person
        . IfNotDefault(x => x.Name)
        . IfNotDefault(SomeOperation, x => !string.IsNullOrEmpty(x));


2. Computing average. This nicely works as a part of LINQ chain:

var avg = students
        .IfNotDefault(s => s.Grades) // let’s assume that Grades property returns int array 
        .IfNotDefault(g => g.Average(), g => g != null && g.Length > 0);

Notice one thing. The Average method returns double. If it’s not been possible to compute the average, then the avg variable will be set to 0. Sometimes it’s a desired side effect, other times it’s not.
If it is the latter, we can fix this easily with nullable cast:

        .IfNotDefault(g => (double?)g.Average(), g => g != null && g.Length > 0);


3. Value types

Sometimes we can take advantage of the default struct values.
For example, the default value of double (and other numeric types) is 0.
We can use that fact to implement a division method:

public static double? Div(double dividend, double divisor)
    return divisor.IfNotDefault(_ => (double?)dividend / divisor);

The same thing is possible with booleans. Instead of writing:

return TrueCondition
    ? ComputeSomething()
    : null; 

we can write:

return TrueCondition.IfNotDefault(_ => ComputeSomething());

It’s up to you to decide if it’s overcomplicated or not. For me it’s just a useful tool that suits my needs in some cases.


Better future

There are good odds that in the future the IfNotNull extension will no longer be needed.
It may be replaced by a new Safe Navigation Operator. It’s supposed to be working in the following way:

//member access
obj?.Property; //instead of obj.IfNotNull(x => x.Property);

//method invocation
obj?.Method(); //instead of obj.IfNotNull(x => x.Method());

obj?[0]; //instead of obj.IfNotNull(x => x[0]);

You can read more about it on the Visual Studio User Voice, where Mads Torgersen (the C# Language PM) said: “We are seriously considering this feature for C# and VB, and will be prototyping it in the coming months.”


Jakub Niemyjski

Posted on Wednesday, March 26, 2014 7:45 PM C# | Back to top

Comments on this post: Get rid of deep null checks

# re: Get rid of deep null checks
Requesting Gravatar...
Code snippets render as grey text on black background which I can't read. Suggest a different text colour?
Left by Myopia on Mar 27, 2014 11:11 AM

# re: Get rid of deep null checks
Requesting Gravatar...
Hi Myopia,

I use prettyprint with Sunburst skin. Syntax highlighting happens on the client side - the code is initially grey, then JS performs necessary amendments.

It looks like you have disabled JavaScript in your browser.
Left by nabuk on Mar 27, 2014 1:47 PM

# re: Get rid of deep null checks
Requesting Gravatar...
It doesnt look like less bloated. Actually if and several conditions are more natural, than having multiple lines of these IfNotNull. The possible safe navigation operator looks good, would be nice to have something like
postCode = store?.Address?.PostCode;
One line, intention is obvious, very readable. All IMO :-)
Left by yaroslavya on Mar 27, 2014 1:51 PM

# re: Get rid of deep null checks
Requesting Gravatar...
How about using Expressions? This way you can make just one extension method call, instead of chaining several IfNotNull. Check
Left by Marcin Juraszek on Mar 27, 2014 5:44 PM

# re: Get rid of deep null checks
Requesting Gravatar...

Unfortunately this way is inflexible and unreliable. Consider following examples:

1. new object().IsNull(x => x.GetType().Assembly);
2. new [] { new Version(1, 0) }.IsNull(x => x[0].Major);

Each of them ends up with TargetException being thrown, because there are not MemberExpressions only.

Even if we would support all expression types, that wouldn't help. There could be "good" null instructions, as a part of longer expression, which would be treated as bad ones, or the implementation would have to guess what was the intention.
Left by nabuk on Mar 27, 2014 6:40 PM

# Expression version
Requesting Gravatar...
Short Expression version

public static T SafeRead<T>(Expression<Func<T>> e, T valueIfNullReferenceException)
MemberExpression member = (MemberExpression)e.Body;
return e.Compile()();
catch (NullReferenceException)
return valueIfNullReferenceException;
Left by Stig Christensen on Mar 28, 2014 9:06 AM

# re: Get rid of deep null checks
Requesting Gravatar...

Intercepting NullReferenceException is bad either, because it might hide implementation errors.

What if you would call, as a part of expression, the following method?

public int M() { return (new object() as Version).Major; }
Left by nabuk on Mar 28, 2014 10:00 AM

# re: Get rid of deep null checks
Requesting Gravatar...
I like the idea, but isn't it an antipattern to have all these null checks?
In my opinion it's also a violation of the Law of Demeter. Of course, in some cases you need null checks, but I try to avoid them as much as possible.
Left by Georg on Mar 28, 2014 10:28 AM

# re: Get rid of deep null checks
Requesting Gravatar...

It's just a tool. It would be an anti pattern to check all objects for nullity.
If you don't expect to get null from a method, then it's right to allow NullReferenceExpection to be thrown. On the other hand you expect FirstOrDefault extension to return null sometimes and you have to handle this scenario appropriately.

About the Law of Demeter, here is a nice discussion about it, in the context of Safe Navigation Operator:
Left by nabuk on Mar 28, 2014 11:17 AM

# re: Get rid of deep null checks
Requesting Gravatar...
The title and the content of the article disagree. You're not getting rid of deep null checks, you're just moving them! And you've made the null-check much more complicated! I'd like to explore how/when to remove unnecessarily defensive code. Or some guidance on where null checks and default value assignment is best applied.
Left by Anthony Mastrean on Mar 31, 2014 8:25 PM

# re: Get rid of deep null checks
Requesting Gravatar...
Hey Jakub, this tutorial on getting rid of deep null checks was simply great. Thanks a lot for sharing. We have some tutorials as well that may benefit your readers at
Left by seth williams on Jul 17, 2014 11:19 AM

Your comment:
 (will show your gravatar)

Copyright © Jakub Niemyjski | Powered by: | Join free