sharp bites

standing on the shoulders of giants

Nullable Types and the Coallescence Operator

I’m going to talk a bit about a couple of nice features introduced in .NET 2.0. It’s nothing new, but it’s sweet anyway.

Nullable Types
Nullable types address the scenario where you want to be able to have a primitive type with a null (or unknown) value. This is common in database scenarios, but is also useful in other situations. This is a PITA to deal with in .NET 1.1, and you have to do some boxing or wrapping to get along with it.

Since .NET 2.0 we have Nullable Types, a much cleaner way to do it.
Nullable Types are declared either as:
System.Nullable variable
or the simpler way:
T? variable
where T is the underlying type of the nullable type. T can be any value type including struct; it cannot be a reference type.

Examples of Nullable Types:
int? i = 10;
double? d1 = 3.14;
bool? flag = null;
char? letter = 'a';
int?[] arr = new int?[10];

To do a null check we could write:
if (i.HasValue) {...}
but again we can just simplify it to:
if (i != null) {...}

Nevertheless, there are a few things to consider when dealing with nullable types:

int? n = null;
//int m1 = n; // Will not compile.
int m2 = (int)n; // Compiles, but will create an exception if x is null.
int m3 = n.Value; // Compiles, but will create an exception if x is null.

int? a = 10;
int? b = null;
a++; // Increment by 1, now a is 11.
a = a * 10; // Multiply by 10, now a is 110.
a = a + b; // Add b, now a is null.

Comparisons: If one of the nullable types is null, the comparison evaluates to false
int? num1 = 10;
int? num2 = null;
if (num1 >= num2)
System.Console.WriteLine("num1 is greater than or equal to num1");
// num1 is NOT less than num2. --> WRONG ASSUMPTION!!!

The bool? nullable type can contain three different values: true, false and null. As such, the cannot be used in conditionals such as with if, for, or while. It would give a compilation error.
bool? b = null;
if (b) // Error CS0266.

The ?? (Coalescence) Operator
The ?? operator defines a default value that is returned when a nullable type is assigned to a non-nullable type.
int? c = null;
// d = c, unless c is null, in which case d = -1.
int d = c ?? -1;

This operator can also be used with multiple nullable types. For example:
int? e = null;
int? f = null;
// g = e or f, unless e and f are both null, in which case g = -1.
int g = e ?? f ?? -1;