Click here to Skip to main content
16,018,938 members
Articles / All Topics

A Lot About Nothing (or null)

Rate me:
Please Sign up or sign in to vote.
4.57/5 (6 votes)
17 Mar 2010CPOL2 min read 14.3K   3   7
A lot about nothing (or null)

Introduction

I believe that the code you write should express your intended functionality in a manner that reads almost like a story. To achieve this, you need to use a coding style that includes descriptive names for methods, properties, and fields. One area that a lot of people don’t consider is what their code says when they use null in C# or Nothing in VB. Used incorrectly, it can result in confusing code and subtle errors.

So let's start our null using code to English translator and examine some code idioms.

Initializing a Variable to null

This is the simplest of statements:

C#
ISpoon aSpoon = null;

This means “I’m probably going to use a spoon at some point in this class or method, but I haven't decided which one, haven’t been given one, or haven’t made one yet.” Another way of say this is “There is no spoon”.

Notice that the variable was defined in terms of the interface ISpoon. The reason for this is that there are many different types of spoon (silver, coffee, sugar, serving, wooden, …) and I want to be able to use the most appropriate for a given situation.

Assigning null to a Variable

Take the following code:

C#
ISpoon aSpoon = GetAWoodenSpoonFromTheDrawer();

theCook.StirsSauceWith(aSpoon);
aSpoon = null;

In this situation, you have gotten a spoon and used it. The assignment says “I’m done with this spoon and don’t care about it anymore. I’ll just drop it wherever, and the cleanup crew (the garbage collector in .NET) will pick it up, wash it, and put it back where someone else can use it”.

Returning null from a Method

Methods will typically return either a single value or a collection of values. For the single value returning method, returning null will mean something different depending on the intent of the method. For example,

C#
ISpoon aSpoon = GetAWoodenSpoonFromTheDrawer();

would mean to me that there wasn’t a wooden spoon in the drawer. Now you will have to check that aSpoon is not null before using it and chose a different type of spoon, or get a wooden spoon elsewhere. Personally, I find this type of code detracts from the flow of the code’s story and prefer to throw an exception as the exception can tell you what went wrong. So instead of:

C#
ISpoon aSpoon = GetAWoodenSpoonFromTheDrawer();

// couldn't get a spoon from the drawer
if (aSpoon == null)
    aSpoon = FindAWoodenSpoonElsewhere();

// use the spoon if one was found.
if (aSpoon != null)
{
    ...
}

I would write:

C#
ISpoon aSpoon = null;
try
{
    ISpoon aSpoon = GetAWoodenSpoonFromTheDrawer();
}
// there isn't a spoon in the drawer
catch (NoSpoonFoundException)
{
    // look elsewhere
    try
    {
        aSpoon = FindAWoodenSpoonElsewhere();
    }
    // No spoon found anywhere
    catch(NoSpoonFoundException)
    {
        aSpoon = BuyAWoodenSpoon();
    }
}
// there was a spoon, but it was dirty
catch(DirtySpoonException)

{
    WashDishes();
    aSpoon = GetAWoodenSpoonFromTheDrawer();
} 

// use the spoon if one was found.
if (aSpoon != null)
{
...
}

For the case where the method returns a collection of items, as in:

C#
ICollection<ISpoon> mySilverSpoons = GetAllSpoonsThatAre("silver");

returning a null does not say “There are no spoons”. Rather, it says “I couldn’t create a collection of spoons”. In this case, I would return a collection with no items. As before, errors should throw exceptions. This means that you can safely iterate the collection returned. The usage pattern would look like:

C#
try
{
    ICollection<ISpoon> mySilverSpoons = GetAllSpoonsThatAre("silver");

    foreach(var spoon in mySilverSpoons)
    {
        Polish(spoon);
    }
}
catch(MissingSilverwareBoxException)
{
    CallPolice();
}
catch(NoPolishAvailable)
{
    Order("Polish");
    Reschedule("Polish Silver Task");
}

Due to time constraints, I’m not going to address null parameters in this blog.

I hope this has given you something to think about when architecting/designing you applications. Just remember Nothing (or null) can hurt you if you don’t think about Nothing.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) CodeProject
Canada Canada
As Senior Architect, Matthew is responsible for the Architecture, Design, and Coding of the CodeProject software as well as Manager of the Infrastructure that runs the web site.

Matthew works on improving the performance and experience of the Code Project site for users, clients, and administrators.

Matthew has more years of software development, QA and architecture experience under his belt than he likes to admit. He graduated from the University of Waterloo with a B.Sc. in Electrical Engineering. He started out developing micro-processor based hardware and software including compilers and operating systems.
His current focus is on .NET web development including jQuery, Webforms, MVC, AJAX, and patterns and practices for creating better websites.
He is the author of the Munq IOC, the fastest ASP.NET focused IOC Container.
His non-programming passions include golf, pool, curling, reading and building stuff for the house.

Comments and Discussions

 
GeneralNot really Pin
DaProgramma23-Mar-10 1:41
DaProgramma23-Mar-10 1:41 
I appreciate that someone thinks about semantics of programming constructs. I do this myself for quite some time, to make our software more readable and understandable by humans.
But I have other opinion about null values, parameters as well as function returns. PLease consider

Person p = loadedPersons.Find( "Meyer" );

You would not use exceptions to signal that the person is not yet in the cache? Returning null is the right answer here.

In general, whether null should be allowed or not depends on the contract:

- when "not found" etc. is part of the contract, i.e. it is perfectly valid that the function may not find something, then returning null is the only correct decision.

- when the function cannot fulfil its contract, then it must not return anything, even not null. The way to express this is by means of exceptions.

Example for the first case:

Person p = loadedPersons.Find( "Meyer" );

Example for the second case:

int result = calculateSquareRoot( -1 );

Greetz
daProgramma
GeneralRe: Not really Pin
Matthew Dennis23-Mar-10 7:10
sysadminMatthew Dennis23-Mar-10 7:10 
GeneralRe: Not really Pin
DaProgramma23-Mar-10 8:18
DaProgramma23-Mar-10 8:18 
GeneralSpoon-power! Pin
CurtainDog22-Mar-10 22:26
CurtainDog22-Mar-10 22:26 
GeneralRe: Spoon-power! Pin
Matthew Dennis23-Mar-10 7:03
sysadminMatthew Dennis23-Mar-10 7:03 
GeneralI don't agree with using try catch Pin
Micke D22-Mar-10 13:33
Micke D22-Mar-10 13:33 
GeneralRe: I don't agree with using try catch Pin
Matthew Dennis22-Mar-10 14:55
sysadminMatthew Dennis22-Mar-10 14:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.