1 May
2010

Say “No” to “Null”

Category:UncategorizedTag: , , , :

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.

25 thoughts on “Say “No” to “Null”

  1. I have tried this. However, I have the following scenario, and I cannot figure out a why to remove the zillion null checks: I write web services which are called with complex objects (eg, a person info, which contains a list of contact infos, which can contain phone numbers, addresses, emails and so on; the person info also contains birth date, social security number and a lot of other stuff).

    Now, the PersonInfo object is very deep – probably five or six levels – and quite wide too. I am reluctant to write large if/switch statements in the main method of the web service – instead, I just send the PersonInfo object to a method, which in turn will send its sub-objects to other methods, and so on, and each method checks its inputs.

    Of course, this DOES lead to the occasional “crap, I forgot to check for null here”… so I’d be more than happy if you could point out how I can solve this in a more elegant manner.

  2. My turn to play devil’s advocate. 🙂

    The problem is that sometimes the null is the most appropriate value. Even when dealing with numbers, there is a difference between 0 and null. Say you are dealing with an average, if one of the values is 0, that affects the value. But if the value is null, you need to completely ignore the value (it should not be part of the count).

    Now, if someone issues a search for a particular item (say a customer by name), null means the person was not found.

    But, if you really have no idea of how to handle a null value (and return a null is not an option), you should use an Debug.Assert. Unfortunately, asserts are vastly under used in .net.

    Complications arrise with larger applications with complicated database schemas. The unfortunate truth is that our default for column creation is to use nullable types…which can cause issues down the road.

  3. @Marcel Popescu
    One possible solution in your case is to create a method that validates each person object that comes through the webservice and does whatever rules you would have done in methods down the line. Even if you are dealing with null there, (which you may have to because it is a boundary that you don’t have control over), you are preventing the nulls from flowing down into the rest of your application.

    There are many instances where you can replace something can can be nullable with a list of something instead and use rules to ensure the list is of max size 1. Consider address on a person. Normally you would see a data structure that might look like Person.Address. Well, if address can be null, then you could also change it to Person.Addresses, and let that be a list. The change is subtle, but in methods that use person and use the address, they can now use a foreach loop to do something for the address, and if none is found they automatically do nothing for the address.

    It is very situational, it is pretty hard to suggest a solution without seeing code, but I would lean towards eliminating nulls upstream as much as possible or makes sense.

  4. @Mathias
    I looked at code contract, but perhaps I should give them another look. When I first had considered them, I thought they were a little burdensome and difficult to implement.

  5. @Chris Brandsma
    I’m not sure I would say null is the most appropriate value, although I see your point. There are many instances where wrapping an primitive into an object can solve that problem.

    For the searching for a customer by name, I would prefer to return something like an empty list rather than null.

    You are right though, in that there are going to be instances where you are going to have to deal with and handle nulls. I just prefer to minimize those, as opposed to trying to handle them in every method, and to try to not let nulls cross the method call boundary.

    You would be pretty surprised how many times you can actually get rid of null if you try. It is more than you would think.

  6. I always check for null parameters in public methods if I want to do something with it, an ArgumentNullException(“paramName”) is always more helpfull than some NullReferenceException.

  7. I’d still check for nulls based on the idea that you want to detect an error condition as early as possible. One real problem is that programmers often use null to indicate a legitimate state in their programs. The most common issue I’ve seen is that null is often used to mean “empty” or “not found”. That’s a mistake in my book. For instance, if you’re returning a list, returning an empty list is better than returning null.

  8. Yes, sometimes Null means something, but to get your code clean you could do something like this

    NO_CUSTOMER_FOUND = null;


    if (customer == NO_CUSTOMER_FOUND)….

    Then it is much cleaner, easier to understand the intention and of course you will be doing this for a particular case, not all over the place 🙂

    You could employ the same technique for int or other objects.

  9. @Nicolas
    My point is that it’s a mistake overload null to mean NO_CUSTOMER_FOUND. An “Empty” or “Invalid” customer serves the same purpose better.

    if (customer.IsEmpty())… or

    if (!customer.Valid())…

  10. @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.

  11. 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.

  12. 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?

  13. @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).

  14. 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.

  15. @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.

  16. John –

    Timely article as I had just read Robert Martin say the same thing in his book “Clean Code” (which all developers should read).

    Both you and Bob did not say “No Null” (like the popular “No SQL”). I think that, through the comments, it has been clarified that we are talking about the objects created in code. Since a database is external, you probably should do some null checks (especially if you pass datasets around).

    Of course, like anything, this will work only as well as your testing goes, especially the end-to-end testings. If Bob didn’t follow the standards and passed in an uninitialized and that code makes it to production…the response will most likely be a null object check and Bob will probably never hear about it (unless of course, we decide to enforce the programming standards).

    Enjoyed the article and will bring it up to my group today.

    Chuck

  17. There is a difference between passing an invalid null argument to a method and receiving a null return value from a method you called. Null arguments are checked in preconditions (like Code Contracts), and should therefore be checked and dealt with as early as possible. Null return values may be legitimate and generally need to be handled on a per case basis (although you still have empty lists and exceptions where relevant).
    My question is: if I have an internal method which is called by a lot of different public-facing methods that don’t care about the value (they are just passing it on), should the null-check still be in each public method, or can I put a single check in the internal method?

  18. @Chuck
    @Schmuli

    Thanks Chuck, I appreciate the feedback. I think you get my point exactly.

    Schmuli,

    To answer you question, in my opinion the check belongs in the public facing methods. Now, there is a difference between public methods and public facing methods. If you have a class that you are using internally with public methods, I would lean towards practicing the reduction of use of nulls and checking there. But if you truly have an external API beyond your control, you need to not only check the input for nulls, but treat the input as malicious, and do whatever protection is needed. The place to do it is at the point of entrance.

  19. Interesting.

    I’m not sure if I agree but I can see the merit in your argument. Do you also use SAL annotation to help verify that you code is not capable of passing null into your methods?

Comments are closed.