Skip to main content

Development

Chained null checks

Introduction

Regarding to “NullReferenceException”, which is familiar to most of the programmers, because it is very likely to occur “NullReferenceException” when accessing a nested object property. For instance, opportunity.Contact.HomeAddress.Street, if any of the opportunity, Contact or HomeAddress is null, it throws “NullReferenceException”. This blog, will introduce you a easy extension method, which can void redundant chained null check, what’s more, it also can improve the readability of the code.

Chained null checks extensions

First, let’s take a look how to get “Street” in a normal way.

 

string street = null;

if (opportunity != null && opportunity.Contact != null && opportunity.Contact.HomeAddress != null)

{

    street = opportunity.Contact.HomeAddress.Street;

}

 

This is still not too complex, but sometimes we need apply some business logic along with it:

 

string street = null;
if (opportunity != null && opportunity.Contact != null && opportunity.Contact.HomeAddress != null)
{
If(opportunity.Contact.HomeAddress.Street == null)
{
    street = “Nanhuan Road, Hangzhou”;
}
else
{
    street = opportunity.Contact.HomeAddress.Street;
}
}

 

Now it turns a little bit more complex and not that readable enough. What’s more, in the real project, the situation may double or more complex than this sample.

 

So, any ideas that can avoid so much is else statement and the null check? The answer is yes.

If you know F#, which is a functional programming language, I guess it should be very easy for you to understand the following solution. If you don’t have any experience with F#, don’t worry – because it is really very straightforward and easy for understanding.

 

In order to give you a feel to the chained null checks extensions, let’s rewrite above samples first.

 

string street = opportunity.With(o => o.Contact).With(c => c.HomeAddress).With(ha => ha.Street);

and

string street = opportunity.With(o => o.Contact).With(c => c.HomeAddress).With(ha => ha.Street).Return(s => s, "Nanhuan Road, Hangzhou");

 

Isn’t this brief and easy to understand?

 

Ok, now let’s take a little bit more time to look into these Extensions themselves.

 

 

With

Below is the definition of the With extension method.

 

public static TResult With<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator)
            where TResult : class
            where TInput : class
        {
            if (o == null)
            {
                return null;
            }
 
            return evaluator(o);
        }

 

As you can see, if the input is null, then it return the value of the evaluator, which is a function/method provided by yourself. Take above rewrote samples for example,

 

opportunity.With(o => o.Contact)

 

o => o.Contact” is the self-defined evaluator, which means get Contact property from o. So the meaning for “opportunity.With(o => o.Contact)” is, if opportunity is null, then return null, otherwise return Contact property value from opportunity.

 

 

Return

 

And for Return extension method.

 

public static TResult Return<TInput, TResult>(this TInput o,
          Func<TInput, TResult> evaluator, TResult failureValue)
            where TInput : class
        {
            if (o == null)
            {
                return failureValue;
            }
 
            return evaluator(o);
        }

 

Return extension has one more parameter than With extension – failure value.

 

opportunity.With(o => o.Contact).With(c => c.HomeAddress).With(ha => ha.Street).Return(s => s, “Nanhuan Road, Hangzhou”);

 

let’s split above statement to smaller ones.

 

opportunity.With(o => o.Contact)                          // return Contact property value from opportunity if opportunity is not null

With(c => c.HomeAddress)                                    // return HomeAddress property value from contact if contact is not null

With(ha => ha.Street)                                            // return Street property value from homeAddress if homeAddress is not null

Return(s => s, “Nanhuan Road, Hangzhou”);        // return street property value if street is not null, otherwise return “Nanhuan Road, Hangzhou”

 

 

Attached “MaybeMonad.cs” is created by “Dmitri Nesteruk” and he had a good article in CodeProject have given more detailed introduction about this Chained null checks.

Reference: http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Pascal Long

More from this Author

Follow Us