.comment-link {margin-left:.6em;}
Books & Articles I wrote.

Wednesday, January 25, 2006

 

Nullable Types and Null Coalescing

Whilst thinking about how i used DBNull in C# in the past, wanted to consider how to best use the C# 2.0 features to really improve how I manage it all. My discovery is that there are some very cool new features in the languages and that setting magic numbers (Int32.MinValue) and so on to represent nulls can be a thing of the past!!

C# 2.0 uses the "?" type modifier that can be applied to all value and reference types to provide a nullable type of the underlying value type.

So, i can't do:

int age = null; //people don't want to tell me their age

and so i had to do

int age = Int32.MinValue;

or

int age = -1;

Now, however, i can just write:

int? age = null;

So if someone doesn't supply an age, i don't need to pretent their -1 or 150 just to get away from the fact i can't say they didn't tell me. Very coo. Read more here.

Unfortunately, you still have to use DBNull.Value as there is no implicit conversion from a .Net nullable type to a SQL Server nullable type. So you can't take a .Net int? that is null and just save this as NULL into the database, say by passing it as the value to a parameter on a Command. It throws an exception saying that you haven't even passed the parameter - although you have! Change it to a non-null value or a DBNull.Value and it works fine.

I do find this a little irritating and wouldn't mind knowing the reason behind it. Fortunately i did find some code that can help with this here from Manoj.

static object GetDbValue<t>(Nullable<t> val) where T : struct
{
if (val.HasValue)
{
return val.Value;
}
else
{
return DBNull.Value;
}
}


So this can be called from each of your data classes.

BUT, we're not done yet. A very cool feature is the null coalescing operator which is coded as "??". It allows you to set the value of nullable type and return the first non-nullable value.

So :

int? oldSalary = null;
int? newSalary = 27000;
int? currentSalary = oldSalary ?? newSalary


... will set the currentSalary to 27000, as this person has just joined and has no oldSalary.

Even nicer is that you can chain a load of these together, a simple example as below:

int? oldSalary = null;
int? currentSalary = null;
int? newSalary = 27000;
int? workingSalary = oldSalary ?? currentSalary ?? newSalary;


In this case it evaluates from left to right and sets the nullable workingSalary variable to the first non null value that is found - otherwise the result will be set to null (if they are all null).

You can even provide a default constant value, in which case the instance variable to which the result is placed can be nullable or value type. So say we wanted to modify the above, we could do.

int? oldSalary = null;
int? currentSalary = null;
int workingSalary = oldSalary ?? currentSalary ?? 27000;


So that's it for now. Very cool stuff though.

This page is powered by Blogger. Isn't yours?

Weblog Commenting and Trackback by HaloScan.com