.NET 2.0 introduced Nullable value types. As you surely know by now, you cannot set a value type to null. Here”s an example:
Int32 myVar = null; //error: myVar cannot be set to null
This can be easily solved by transforming myVar into a Nullable type:
Nullable<Int32> myVar = null;
If you prefer, you can apply the ? suffix to the variable type:
Int32? myVar = null;
Nullable value types are great when, for instance, you”re getting a value from a table”s column and that column can have NULL. In fact, C# 2.0 has even introduced the coalescing operator (??) which is rather cool when you”re checking for null:
Int32 myVar = null;
Console.WriteLine( myVar ?? 123);
The main objective of this post is not to talk about nullable value types. In fact, there are already some great posts on this…for instance, check this post by ScottGu.
What most people still haven”t understood is that nullable value types are, in fact, supported by the CLR. You can see this in Boxing/Unboxing operations. To understand what”s going on, let”s present an example. Suppose you have a method that expects an Object parameter and you”re passing a Nullable<Int32> which is set to null. If the CLR boxed the Nullable<Int32> (don”t forget that Nullable is a struct!), then you”d get a “valid” object in the method,even though the Nullable<Int32> is set to null.
To solve this,the CLR will always check the value of the Nullable<T> variable and if it”s null, it will simply pass null instead of running boxing operation over that value type. A similar thing happens with unboxing. When you do that, the CLR will convert the boxed instance to T or Nullable<T>. Typically, when you perform an unboxing operation, the CLR won”t allocate heap memory (this is what happens when you have a non null nullable value boxed). However, when you have a null Nullable<T> value boxed and you unbox it, the CLR will have to allocate memory (in the heap) to save that value.
Another place where the CLR treats Nullable in a special way is when you call the GetType method. Calling this method means getting the type of the instance over which you”re calling the method. However, in this case, calling GetType over a Nullable<T> instance will always return T instead of Nullable<T>. The CLR will also treat interface methods specially when you call them over Nullable<T> instaces: it will always cast T to interface instead of Nullable<T>!
As you can see, this behavior is necessary so that things “works as expected” making nullable value types transparent to the programmer.
You might find strange that I”m still writing posts about C# 2.0. After all, we”ve already got C# 3.0, right? I”ve decided writing about some 2.0 features because I”ve noticed that many C# programmers still don”t understand how some of the 2.0 stuff works and without getting those features right, you won”t be able to get much from C# 3.0. So you can expect to see more about C# in the next couple of days (that is, If I manage to find some free time to write about it:))