Some C# obscurities

I’m sure everyone’s tired of hearing about C# 3.0 features like lambda expressions, extension methods, anonymous types and so on.  Before you fall in love with the new features, there are a few oldies-but-goodies that revolve around the “?” character.  I use a couple of these to stump interviewees who proclaim themselves to be C# experts.  These question marks can provide a much cleaner, terser syntax for some fairly common C# usage patterns.

Conditional operator

This one can be easy to abuse, but it provides a nice terseness to code that has conditional assignments:

if (hoursTraveled > 0)
    speed = distanceInMiles / hoursTraveled;
    speed = 0;

I’m trying to calculate speed, but clearly I don’t want to get DivideByZeroException.  Sometimes these types of assignments can add up, so I like to condense them down with the C# conditional operator:

speed = hoursTraveled > 0 ? distanceInMiles / hoursTraveled : 0;

Now the conditional assignment can be written on a single line.

I don’t see this feature used very often, so there is a tradeoff in familiarity.  If the conditional or assignment statements grow too large, it can start to hurt readability, so just use your best judgement on this one.

Nullable types

The release of the .NET Framework 2.0 brought along a little struct type that solved a whole heap of problems.  Value types (structs) can be used to represent types that don’t care about referential identity.  For example, if I have the number 2, and you have the number 2, they’re the same number no matter how many times we create it.

Value types have another interesting aspect, they can never have a null value.  The details behind this are exciting if you like things Jeffrey Richter style, full of heap and stack knowledge, but in the end you just need to know that C# structs can never be null.  This line does not compile:

int i = null;

But not every system in the world that deals with “int” recognizes this rule.  Databases and XML schemas are two examples where “int” values can be null.  To handle the impedance mismatch of real-world nulls and CLR-land value types, the Nullable<T> generic value type was introduced.  By declaring a variable to be Nullable<int>, I can now do this:

Nullable<int> i;
i = null;

Assert.That(i.HasValue, Is.False);

i = 3;

Assert.That(i.HasValue, Is.True);
Assert.That(i.Value, Is.EqualTo(3));
Assert.That(i, Is.EqualTo(3));

Note that I have no problems assigning int values to the Nullable<int> type, as the appropriate cast operators have been defined.  Declaring a nullable type is fairly ugly using the full generic notation, so C# has a nice shortcut:

int? i;
i = null;

There’s our friend the question mark.  It’s telling us “I think this variable is an int, but I’m not sure?”.  This is just another compiler trick C# uses, just like extension methods.  At compile time, “int?” is replaced with “Nullable<int>”, so it’s really just a shorthand way of expressing nullable types.

Before nullable types, I had to use a bunch of dirty tricks to represent nulls in my entities, usually with magic numbers and values like “Double.NaN” or “DateTime.MinValue”.  Nullable types let me bridge the gap between the nullable and non-nullable worlds.

Null coalescing operator

This is the one I love to stump the self-proclaimed experts with.  I draw this on the whiteboard:


And ask them, “what does this operator do in C#?”  Usually I get the crickets, but the special few can tell me about the null coalescing operator.  The null coalescing operator is very similar to the conditional operator, but with the conditional built-in.  I find myself doing this quite a lot with nulls:

if (category.Description == null)
    output = "<Empty>";
    output = category.Description;

I have a value that could potentially be null, in this case the description of a category, but I need to output that value to a friendly format.  Unfortunately, nulls aren’t always too friendly to end-users.  Let’s try the conditional operator to see how that cleans things up:

output = category.Description != null ? category.Description : "<Empty>";

But these conditionals can get ugly, so I can use the “??” operator to provide an even terser syntax:

output = category.Description ?? "<Empty>";

All of these representations are equivalent, but I like the short and sweet syntax the “??” operator provides.  Someone not familiar with this operator might not have any clue what the code does, so there is some level of risk involved.

But I generally don’t like to let a lack of knowledge with a built-in language feature deter me from using it, especially if it can provide a much cleaner syntax.

And as always…

If the syntax and usage these little question marks provide don’t provide better readability (solubility?), then don’t put them in.  These features are there to help, not to satisfy technical fetishes.  As always, keep in mind that your end goal is better readability and better maintainability, not a checklist of features used.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in C#. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • silky

    i wouldn’t call the ternary operated ‘obscure’ by any means.

    also note that you can divide by zero legitimately, if you use doubles.

  • ReSharper kindly reminds me when I forget to use a ternary. Gotta love it!

  • Your Uncle Bob

    Didn’t know about the null coalescing operator.

    Of course, if you put much stock in that as an interview question, I’d be inclined to think you’re just another blow-hard who likes to demonstrate his knowledge about semi-arcane topics during an interview, rather than finding out how qualified an applicant is.

  • The conditional operator with nullables can sometimes be a bit confusing. For example, this causes an error:

    DateTime? dateTime = n > 1 null : Datetime.Now;

    You must cast the null:
    DateTime? dateTime = n > 1 (DateTime?) : DateTime.Now;

    Coditional operator, obscure?

  • @Uncle Bob

    I only ask that for folks that tell me they’re experts. If anyone tells me they’re an expert in anything, I’ll test the limits of their knowledge.

    I like to see the reactions to threats on egos. Humility and patience coupled with passion are what I look for. I don’t care if they know what it means, I like to see if they react negatively “oh NO ONE uses THAT feature! Ask me a GOOD question!” or positively “Hmmm I’ve never seen that. Here’s where it might be good, here’s where it might be bad.” That tells me plenty if I can trust them to be in front of a customer or not.

    If I ever proclaim myself an expert, I hope someone else has the kindness to knock me down a few notches.

  • @Peter

    Obscurities was a bad choice in title, methinks….title about question marks seemed hokey.

    I tend to use the conditional operator fairly sparingly. The slightest amount of complexity in the statements kills any readability the operator gives me.