Ask any programmer what ‘null’ means in C#, 99% of the time you will hear an answer that closely resembles this:
“Null – Amounting to nothing, non-existent, absent of value”.
Seems legit. But the really interesting thing about this definition is that it’s completely wrong. This is in fact, the English language definition of the word.
Now lets look at the actual C# definition of null:
“The null keyword is a literal that represents a null reference, one that does not refer to any object.”
And the Java definition of null:
“null is the reserved constant used in Java to represent a void reference i.e a pointer to nothing.”
What null means in C# & Java is simply that a pointer is invalid, eg. it does not reference a valid object in memory, nothing more. And yet almost every program I see abuses this simple concept by overloading the null keyword with additional semantics from the English language definition.
One very common example of this is in implementations of the repository pattern. The common convention is that when querying the repository, a return value of null indicates that no data was found for the given search criteria.
var item = myRepository.Get(id = 10);
if (item == null)
{
return "no item found with Id: 10";
}
// Do something with item...
It is often said that using Exceptions to control program flow is a bad idea. Given our new found understanding of the null keyword in C#, can we honestly say that using invalid pointers is any better?
What are the alternatives?
Lets think for a second about what we’re actually trying to say he when we return null from our repository. We’re trying to express the fact that the value may or may not be present. There is a data type in all programming languages that is perfectly suited to express this dichotomy – boolean.
In functional languages we can use Maybe/Option monads. In object oriented languages we can use the Null Object Pattern. However I think the simplest and most concise approach is to use the tester-doer pattern as described in Framework Design Guidelines (sometimes called the try/can pattern).
if (myRepository.RecordExists(id = 10))
{
var item = myRepository.Get(id = 10);
}
else
{
return "no item found with Id: 10";
}
This can be optimised to avoid two queries to the database:
var item;
if (myRepository.TryGetItem(id = 10, out item))
{
// Do something with item...
}
else
{
return "no item found with Id: 10";
}
The resulting code is far clearer, and the null keyword is no longer being abused.

3 Comments
This pattern doesn’t feel right for the situation you’ve described. The framework guidelines state: “Consider the Tester-Doer pattern for members that may throw exceptions in common scenarios to avoid performance problems related to exceptions”. The repository isn’t going to throw an exception though if it doesn’t find the entity being requested. It’s the calling code that may throw an exception if it doesn’t gracefully handle the repository returning null. In the OO world, I feel the Null Object pattern is a better fit. Of course, functional language designers solved this problem decades ago
The situation suggested by Framework Design Guidelines isn’t the only place the pattern should be used. If you step back a little you can see that it could come in useful in a whole bunch of scenarios. In any case, who’s to say a repository won’t throw an exception when it can’t find a record? If you’re using something like Linq2Sql the difference between an exception and a null could be as little as Single() vs SingleOrDefault().
The question is, what is the repository trying to tell you by returning a null pointer? And can that message be expressed in a clearer way?
The NullObject pattern is indeed a far better fit, but in my experience it’s a very difficult pattern to implement across an application, especially to retrofit into an existing codebase.
Anyway the point of the post was just to highlight the fact that there is the dual meaning to the word ‘null’ and I think it’s important that we bare that in mind
JimJams…wheezyaikidoka…you sure have some strange aliases