Compsoft Flexible Specialists

Compsoft plc

Compsoft Weblog Compsoft Website News Archive Privacy Policy Contact Us  

Monday, July 20, 2009

C# coalesce operator (double question mark) gotcha

I'm sure you've met the C# coalesce operator, where you can use a double question mark to check for null:

x = y ?? z;

... being equivalent to:

if (y != null)
    x = y;
else
    x = z;

It's a handy shortcut, but sometimes it doesn't behave quite as you I might expect.

Here's an example:

I wanted to combine the elements of an address to make a field that was searchable with a SQL LIKE statement. As we use LINQ to SQL, I needed an expression that LINQ to SQL could translate into SQL syntax. I wrote this:

...
select new
{
    SearchableAddress = c.Address.HouseName   ?? "" + " "
                      + c.Address.HouseNumber ?? "" + " "
                      + c.Address.Road        ?? "" + " "
                      + c.Address.Town        ?? "" + " "
                      + c.Address.County      ?? "" + " "
                      + c.Address.Postcode    ?? ""
}

I'm using the coalesce operator to replace nulls with empty strings - otherwise SQL returns NULL for the whole expression if a single element is NULL.

However, I found my search was rarely getting any matches, and a little digging isolated the above expression as the culprit.

It turns out that the coalesce operator takes lower precedence than the concatenation operator. What I meant (and what I should have written) was this:

...
select new
{
    SearchableAddress = (c.Address.HouseName   ?? "") + " "
                      + (c.Address.HouseNumber ?? "") + " "
                      + (c.Address.Road        ?? "") + " "
                      + (c.Address.Town        ?? "") + " "
                      + (c.Address.County      ?? "") + " "
                      + (c.Address.Postcode    ?? "")
}

... but my version without any parentheses was equivalent to this:

...
select new
{
    SearchableAddress =             c.Address.HouseName    ?? 
                        ("" + " " + c.Address.HouseNumber) ?? 
                        ("" + " " + c.Address.Road)        ?? 
                        ("" + " " + c.Address.Town)        ?? 
                        ("" + " " + c.Address.County)      ?? 
                        ("" + " " + c.Address.Postcode)    ??
                         ""
}

Getting back the first non-null element, padded with a superfluous space, was enough to make the search work occasionally enough to be confusing.

Maybe I should have seen it coming, as I'd happily use:

a = b ?? c ?? d ?? e;

to get the first non-null value, but that string concatenation threw me off the scent.

I dunno - to me coalesce feels like a unary operator, so I'd expect it to be evaluated first; it turns out it gets evaluated almost last. What do you think?

Monday, July 06, 2009

Silverlight 3 And Blend 3

Rumour has it, that Silverlight 3 isn't far from release.

Here is a quick list of features I'm really excited about in Silverlight 3 and Blend 3:

Element Property Binding
You won't believe how much I need this in my life! I've written so much back end code to replicate this feature. Now it's all available Silverlight (as it has been in WPF since the start). It means I can wire up one controls property to another controls property. You'll be surprised how much you'll use this!

Behaviors
Another feature that massively increases code reuse. Write that full screen code once and wire it up to anything you can think of!

Team System Source Control Integration
Finally! I won't need to keep checking out files in Visual Studio to modify them in blend! All the usual (not all but most) source control features will be available through Blend.

Samples Data
Cute feature inside Blend to generate sample data so you are able to see what your designs will look like with some close to real world data in your controls.

As of yet, there has been no official Microsoft press on when Silverlight 3 is due but I've seen some hints lying around on the net that July is the month.

If you haven't guessed it yet, I'm excited... bring it!