The Nullable Dot (Post-Xmas C# Wishes, Part 1)

Well Christmas, that traditional time for giving has just gone past. However the TechieSimon blog has nothing to give, apart from strange blog posts. So I thought I’d be cheeky instead. To somewhat belatedly celebrate the time of giving I’m going to do some (metaphorical) asking: For the next few blog posts I’ll talk about some of the things that I’d love Microsoft to add to the C# Language.

My first wish is for a nullable dot operator.

A what?

You heard me the first time. A nullable dot operator.

What’s that about? Well, how often do you write code like this that dives deep into a class to fetch some value…?

string difficultyLevel = _game.World.Difficulty.Value.ToString();

If, like me, you always try to keep classes small and focused on one single responsibility, then chains like that can come up very frequently.

So what happens if _game contains null when you invoke this statement? Well obviously you get a big fat exception. The same thing happens if a null gets returned by any of the properties or methods, other than the very last one on the right (in this example, the ToString() method).

Sometimes there shouldn’t ever be any nulls so an exception is exactly what you want. But personally I find it happens much more often that I expect that intermediate values may sometimes be null, and I don’t care. If something along the way is null, that just tells me immediately that the final result should also be null – without needing to do any more processing.

Support for this situation in C# is very poor. You currently have two possible ways to implement a solution, and neither of them is particularly attractive.

First up, you could just explicitly look for a null value. Like this.

string difficultyLevel = _game == null ? null : _game.World.Difficulty.Value.ToString();

This means the code has become somewhat more complex than you’d probably like. But will it work? Well sort-of. It’ll cover you for a null value in the first variable in the chain. But more commonly I find I’m dealing with problems where a null value could occur anywhere. _game could be null. Or World could return null. Or Difficulty could return null. And so on, and as soon as I get a null, I know the final answer is null and I can stop processing. Dealing with that correctly is – frankly – tedious. Offhand, the least unreadable way I can think of to write the solution is probably this.

string difficultyLevel;
if (_game == null
	|| _game.World == null
	|| _game.World.Difficulty == null
	|| _game.World.Difficult.Value == null
	)
	difficultyLevel = null;
else difficultyLevel = _game.World.Difficulty.Value.ToString();

That’s way too complicated for what is really just a simple nested property look-up (Yes I know, ToString() is a strictly speaking a method not a property, but you know what I mean. It’s being used rather like a property). And not only that but that code has a hidden issue: You’re now evaluating most of the properties (or methods, if there are any in the chain) multiple times. Depending on how much work those properties are doing internally, that may or may not represent a problem. It’s possible to avoid multiple evaluations by caching the intermediate values, but if you do that the code becomes massively more complicated and tedious to write. Did I mention that this is supposed to be a simple one-line nested property look-up?

There is an alternative that at first sight looks simpler. You could catch a null anywhere in the expression in one fell swoop by wrapping the whole thing in an exception handler. Like this.

string difficultyLevel;
try
{
	difficultyLevel = _game.World.Difficulty.Value.ToString();
}
catch (NullReferenceException)
{
  difficultyLevel = null;
}

That may look tempting, but it’s a bad idea. Seriously bad. Like really, really bad.

Why is it bad? Is it because this code still a lot longer and harder to read than a simple property look-up ought to be?

It’s true, it is longer. But no, that’s not the reason.

Is it because, on a philosophical level, this code amounts to an abuse of exceptions? After all, catching and throwing exceptions is a lot of work for the CPU and can hit performance. A principle of good programming in C# is that you use exceptions for exceptional situations. Using an exception to catch a null value when you’re routinely expecting a null value is definitely not good practice.

All true, but no, that’s not the reason I was thinking of.

The real concrete reason is this: By catching and ignoring exceptions that you are expecting, you run the risk that – if your code is buggy and throws an exception that you weren’t expecting, you’ll accidentally ignore that too. Imagine that last week one of the interns mucked about with overriding the Value.ToString() method, and their code is buggy and throws a NullReferenceException that it shouldn’t throw. Yes of course they wrote the buggy code, I know you would never write buggy code. But anyway, you get the idea. You’ve just turned his exception into a corrupt data value propagated to who knows where. Don’t do it!

So, are there any other alternatives?

Well, not really.

Enter my proposed nullable dot operator. The idea is that in this situation you would just write this:

string difficultyLevel = _game..World..Difficulty..Value..ToString();

Where .. is the nullable dot operator. What it means is that wherever the compiler sees .. it replaces it with a normal dot operator, combined with a check that the thing on the left is not null. In other words, the compiler replaces A..B with something like (A == null ? default(B) : A.B)

I’ve used default(B) to cover the case where B is a valuetype.

Although my example involved a deeply nested member look-up, the .. operator would be just as useful for any simple property or method call, whenever you want to handle null references by returning null. And you can even use the same principle for methods that return void. Imagine for example replacing

if (x != null)
  x.Dispose();
  

with

x..Dispose();

Even better, think of all all those null checks that you wouldn’t have to do every time you raise an event!

Personally I reckon this would massively simplify a lot of code. And as C# features go, it would be relatively simple to implement since roughly all it really requires is a fairly trivial code expanding step very early in the compilation process. (Though I admit I’m blindly ignoring the issue that any new C# compiler feature, no matter how trivial, requires a significant investment in testing etc. It’s (not long after) Christmas, Let me fantasize…)

Before I leave the subject, I should point out a couple of technical details.

Firstly, for methods that return void, the compiler rewrite of .. would be a little different – something more like that A..B() becomes if (A != null) {B();}, but the principle is the same.

A secondly, A..B makes sense if A is a reference type or a Nullable <T>. But if A is any value type other than Nullable <T>, then invoking A..anything is usually going to be a silly thing to do. So I’d suggest should be flagged as a compilation error.

So that’s my first post-Christmas wish from Microsoft. The C# Equivalent of the Partridge in a Pear Tree. Well, more precisely, a partridge in a possible pear tree reference that might be null…

Partridge cutie = myPearTree..GetPartridge();

And in case you’re wondering, the line of code I quoted for my earlier example with a game and a difficulty etc. is real. It comes from the Civilization 4 Game of the Month competition – a regular series of competitions I help to run, based on the amazing strategy game, Sid Meier’s Civilization 4. Specifically from an application I wrote that helps analyze the submitted competition entries. If you like Civ4, do check it out. And if you’ve never played Civ4 – you don’t know what you’re missing…

Advertisements

4 thoughts on “The Nullable Dot (Post-Xmas C# Wishes, Part 1)

  1. A valuable, useful, informative, interesting and profound post, Mr Techie Simon. I too would welcome such an operator into the realms of my code with open arms.

    Just one minor point: if the compiler replaced the nullable dot with
    A == null ? default(B) : A.B
    as you suggest, it would suffer from the same issue that you alluded to above, that the A property would be evaluated twice, including double running of side-effects, if any. It would probably actually be better for it to store it in some temporary variable…
    var temp = A; temp == null ? default(B) : temp
    Also, the default(B) syntax probably isn’t right either, you need to get the type of B and default that, I can’t be bothered right now, though.

      1. Well now I’m all up to speed with the Law of Demeter. Perhaps that’s the reason why my View Models on the Service Items project, which exposed domain model objects and allowed the views to access their innards, did not meet with the approval of the suits over at MVVM headquarters.

Comment on this article (your first comment on TechieSimon will be moderated)

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s