in

 

Jimmy Bogard

Assistant to the assistant to the regional manager

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;
else
    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>";
else
    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.

Published Jan 30 2008, 09:40 PM by bogardj
Filed under:

Comments

 

silky said:

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

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

January 30, 2008 10:10 PM
 

Joe Ocampo said:

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

January 31, 2008 12:29 AM
 

Your Uncle Bob said:

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.

January 31, 2008 8:37 AM
 

Peter Ritchie said:

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?

January 31, 2008 9:02 AM
 

bogardj said:

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

January 31, 2008 9:25 PM
 

bogardj said:

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

January 31, 2008 9:29 PM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About bogardj

I'm a senior consultant with Headspring Systems in Austin, TX. My focus is using .NET technologies together with Agile methodologies. Back in 2005, I drank the Agile punch and haven't looked at a waterfall the same since.
Copyright Los Techies 2007. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems