In .NET 2.0, the notion of nullable types has been added. But I have the feeling that lots of developpers miss some basic understanding about this. So I have decided to add here some thoughts and explanation about the nullable types.
Recall on nullable types
Note that a primitive type has the following declaration in the .NET framework:
public struct Int32 : IComparable, IFormattable, IConvertible, IComparable<int>, IEquatable<int>
In comparison, the Nullable<T> class has the following declaration:
public struct Nullable<T> where T: struct
int? i = null;
Console.WriteLine(i);
Console.WriteLine(i.HasValue);
Console.WriteLine(i.Value);
Console.WriteLine(typeof(int?));
Console.WriteLine(i.GetType());
int? j = 10;
Console.WriteLine(j);
Console.WriteLine(j.HasValue);
Console.WriteLine(j.Value);
Console.WriteLine(typeof(int?));
Console.WriteLine(j.GetType());
Recall on the default value (default operator)
On generic types, you have the “default” operator.
This operator returns the default value for a generic parameter type, meaning:
public class GenericClass<T>
{
public override string ToString()
{
object o = default(T);
return o == null ? "null" : o.ToString();
}
public static void Main()
{
GenericClass<int> myInt = new GenericClass<int>();
GenericClass<object> myObject = new GenericClass<object>();
Console.WriteLine(myInt.ToString());
Console.WriteLine(myObject.ToString());
}
}
The nullable types are in fact the structure “Nullable<T>”that expose a method “GetValueOrDefault”. This method will act as the “default” operator in case the nullable types do not have any value.
Basic arithmetic operations on nullable types
int? i = null;
int? j = 10;
int total1 = 0;
if ( i.HasValue )
total1 += i.Value;
if ( j.HasValue )
total1 += j.Value;
Console.WriteLine(total1);
int total2 = i.GetValueOrDefault() + j.GetValueOrDefault();
Console.WriteLine(total2);
It will of course depend of the cases, but usually the second syntax will allow having clearer (and shorter) code.
Comparison operators with nullable types
int? i = null;
int? j = 10;
int? k = 20;
Console.WriteLine(i < j);
Console.WriteLine(i > j);
Console.WriteLine(i == j);
Console.WriteLine(i != j);
Console.WriteLine(k < j);
Console.WriteLine(k > j);
Console.WriteLine(k == j);
Console.WriteLine(k != j);
So you can use the comparison operators without any problem. You don’t need to test the “HasValue” property before doing the comparison. Just keep in mind that this very short syntax is converted by the compiler as follows :
i < j
(i.GetValueOrDefault() < j.GetValueOrDefault()) && (i.HasValue & j.HasValue)
Just note that if you need to do a special treatment in the “null” case, you will have to use the “HasValue” property.
if ( i < j )
{
}
else
{
}