Say “No” to “Null”

May 1st, 2010
I was recently asked to write a fairly simple piece of code.  In this simple piece of code, I didn’t handle a null input.  I was asked about what kinds of things I would consider about the input, and I pretty much knew what the asker was going after.
What do you do if "null” is passed in?
My answer may turn out to be a bit of a surprise.
Nothing, I don’t handle nulls in code that I control the use of.
“What?  What?” you say.  “You don’t handle null?  What kind of heresy is that?”  It is the kind of heresy that helps produce elegant code and I will show you why.

How well do you handle null right now?

Would you say that in most of the code you write you properly check all arguments for null? Or, do you like most developers, handle null in certain cases when you happen to think about it, or after the application dumps a “null pointer exception” stack trace? Be honest, look at your code if you have to. The problem is “d00d ur d0ing it r0ng!” john-mccarthy-programming-completely-wrong Unless you are some kind of anal retentive perfectionist, you are probably not handling null in every single method call.  That means there are huge potential bugs in the code that you are writing which will throw null pointer exceptions.  That is bad, I agree. So, if you are not handling it correctly right now, then what can you do to fix that?

Avoiding null in the code you “own”

You can’t control external libraries.  And you can’t control how people will use your code, but you can control the code you write and you can, to a degree, control the code your shop writes. The better strategy is to never pass null in the first place. You can either focus your efforts on:
  • Checking for null
  • Not ever passing null
    The more elegant solution is to focus on never passing null.  By doing this you will end up writing less code and avoid decisions about how to handle null inside of a method that doesn’t have enough context to decide what to do.
Let’s look at an example:
public string TransmographyThreeStrings(string first, string second, string third)
{
     if(string.isNull(first) || string.isNull(second) || string.isNull(third))
    {
           // hmm, I donno, what should I do?  Should I throw an exception?
           // should I return an empty string?
           // what if the first string wasn't null, can we still do something meaningful?
           // how will the caller of the method know what I will do?
    }

}
You can see there that we are checking each parameter for null.  The problem is we don’t know what we should do.  We have lots of options, but none of them are obvious. How much better is it to make sure that we never pass null into methods, rather than write this kind of code in every method?

What about accidentally passing in null?

Many of you are probably thinking at this point that the main way null gets passed into a method is because someone calls a method without knowing that it contains a null value.
TransmographyThreeStrings("Hello", "World", mysteryObject.Text);
Perhaps mysteryObject.Text is null.  You wouldn’t even know it. Ah, but you can.  Or you can prevent it at least.  Somewhere mysteryObject gets created.  When it gets created its values either get initialized or not.  You can prevent any of its values from being null, several ways:
  • Always initialize variables when they are declared.
  • Use a builder pattern to ensure that objects are always fully constructed before being created.
  • Use properties to provide default values or lazy initialize.
  • Make your objects immutable as much as possible.
The practices that prevent null from accidentally being passed in make your code much more elegant than repeating if blah == null code all over the place. In general, you should always strive to eliminate the passing of null rather than checking for null.  By doing so you reduce extra lines of code in each method, and are forced to use better design practices.

Exceptions

Yes, there are times when you need to check for null.  If you are writing a library that external developers will use, then you will probably want to check for null in all of your methods that are exposed as part of the API.  (On your internal methods, you don’t need to since you have already cleansed the input.) Also, if your code is being used as a callback to some API and you don’t know if it can ever pass null into your code, you probably should check for null. A bad excuse is that other developers may pass null to your method. It is much better as a software shop to put the onus of not passing null on the caller of any method rather than putting it on the writer of the method being called. You will also reduce your exception handling code, because you will have less exceptions for invalid parameters.
As always, you can subscribe to this RSS feed to follow my posts on elegant code.  Feel free to check out my main personal blog at http://simpleprogrammer.com, which has a wider range of posts, updated 2-3 times a week.  Also, you can follow me on twitter here.

  • http://rickyclarkson.blogspot.com Ricky Clarkson

    Maybe FindByName(string name) {
    foreach (var c in customers)
    if (c.Name == name)
    return Maybe.Just(c);
    return Maybe.None();
    }

  • http://rickyclarkson.blogspot.com Ricky Clarkson

    @Ricky Clarkson
    That should have been Maybe<Customer> FindByName(string name)..

  • David JM Emmett

    @Ricky Clarkson throwing a CustomerNotFound exception would stop you from having to return null ;)

  • David JM Emmett

    @Ricky Clarkson alternatively, if there could possibly be more than one Customer with the same name, you would always want to return an array rather than a single Object.

  • http://simpleprogrammer.com John Sonmez

    @David JM Emmett
    @Ricky Clarkson

    List&ltCustomer%gt FindByName(string name)
    {
    List<&ltCustomer%gt customers = new List&ltCustomer%gt();
    foreach (var c in customers)
    {
    if (c.Name == name)
    {
    customers.add(c);
    }
    }
    return customers;
    }

  • http://py-sty.blogspot.com Steve Py

    Dunno, you can coat a turd in icing-sugar but it still won’t be a jelly donut. Granted, I hate NullReferenceException, but always returning a reference to an object that’s been flagged as invalid, or returning a (potentially empty) list of objects is just masking one problem with others.

    What if you forget to put the check in for .IsValid? If you return a list and 90% of the time you’re dealing with 1 expected result you’re going to have to remember to check if the list is empty or not because [0] will net you index out of range exceptions, and similar with Linq’s “First()” unless you use “FirstOrDefault()” in which case you’re exactly back where you started. I fact, I find I need to deal with #null more frequently with Linq since I often find myself using functions like FirstOrDefault().

    Personally I favour to check required arguments and throw ArgumentNullExceptions with the parameter name. These are exceptions, they’re going to need to be raised, recorded, and fixed, or at minimum, presented to the user in a meaningful way… No sugar-coating required. Though I definitely agree that code should always avoid using/returning #null wherever possible. #Null is here to stay, so just be sure to guard against nothing when you expect something.

  • julia

    Hi, I’m not an expert developer.
    I wanna know why we need to avoid null checking in our codes?
    I usually used to check null values especially when I retrieve the result from database.
    eg: JOLInd = (!string.IsNullOrEmpty(ds.Tables[0].Rows[0]["JOLInd"].ToString()) ? ds.Tables[0].Rows[0]["JOLInd"].ToString() : string.Empty);

    checking null is really a bad practice?

  • http://peshir.nl/ peSHIr

    @julia

    How about the three null checks you are not doing in “ds.Tables[0].Rows[0]["JOLInd"].ToString()”? In fact, the six null checks you’re not doing, because you copy pasted that compound expression so you have it two times. The world is (almost always) more complex than you initially think…

    I prefer to check all arguments of public API methods and raising ArgumentExceptions on those as appropriate and then try to use (and check for) as little nulls as possible, for instance by using sentinels where appropriate. Any problems regarding nulls should be found in unit test code or by software testers (through the applications top level exception handling).

  • James B

    I disagree with the no-to-null idea for a number of reasons.

    #1
    I’ve got the ‘don’t trust the caller’ philosophy engrained too deeply in me.

    #2
    There’s no point in making an expensive call to a database, or Active Directory, when I know up front (by checking for null) that the call will fail.

    #3
    If I use that null value in the calls I make, say, to my Oracle database, I’m going to generate OracleExceptions that I either need to handle, or let propagate to the caller.

    If I have to handle them, I’d rather test before-hand, so that I know an OracleException means a true issue calling the database.

    Propagating them to the caller breaks encapsulation. Now the caller has to handle OracleExceptions, and knows how I’m handling my back end. And if I switch to SQL Server? Should the caller have to re-write all of his code to handle SQL Server exceptions?

    Throwing an ArgumentNullException clearly tells the caller he can’t pass null for the Username.

    #4
    Contrary to what the author claims, I DO know what a null value means. If I’m concatenating three strings, and one is null, I’ve decided up front that either (a) a null value can’t be concatenated, or (b) a null value translates to an empty string, which is clearly documented in my XML documentation, and therefore in the help text in the Object Browser.

    I will *always* know what a null value means, because as the designer of the method, I’ve decided up front what it means. And what I say it means is law.

    #5
    You have to be anal retentive, SOMEwhere… the argument that you aren’t checking for null in every method doesn’t hold water – you either have to check for null in the callee, or check for null in the caller. What’s the difference? It’s not acceptable in either one to only check some of the time.

    I mean no disrespect, but this is one of the worst pieces of advice I’ve seen offered in a long time, and all it comes across as is laziness.

  • http://simpleprogrammer.com John Sonmez

    @James B
    Hi James,

    I think you are missing the point.

    What I am suggesting is transferring the energy used to check for null in your codebase to preventing the passing of null into methods.

    You are right you have to check for null somewhere, but in many instances you can “check for null” by writing your code in a such as way that null is not a possibility at all.

    It is very hard to show examples that are not very long.

    But the core of what I am saying here is that effort used to check for null is better spent preventing null.

    The return on this investment is less code and better design. Null tends to be a crutch. Trying to prevent null usually leads to a better design.

    There are public API points where you need to check for null, but once you pass those points, internally you can prevent null from making it further into your codebase.

    Throwing ArgumentNullExceptions is a fairly popular answer, but the problem with that is it is a runtime prevention, which is not a prevention at all. To the end-user a null reference exception is no different than an ArgumentNullException. Either way they end up having the application crash. (Unless you are going to catch ArgumentNullExceptions everywhere.)

    If you tend toward immuatable objects, you eliminate the possibility of any of their fields being null.