C# Nullable Types…Subtlety

While moderating posts over on the Asp.Net forums, I ran into a thread containing questions about using Nullable types.

Nullable types are a simple concept: Allow value types to have the value of null. Typically, an integer or float cannot be null: When in scope, they always exist and therefore must have a numeric value (zero is not null, it is a numeric value).

Here is the subtlety (or in technical terms, a really ooky statement):

Nullable types with the value of null are not really null.

Look at this code:

    int    Test1 = 0;       // standard value type
    int?   Test2 = null;    // nullable value type         
    Object Test3 = null;    // reference type
 
    Response.Write("Test1: " + Test1.ToString() + "<br />");
    Response.Write("Test2: " + Test2.ToString() + "<br />");
    //Response.Write("Test3: " + Test3.ToString() + "<br />");
 
    // Output:
    //
    // Test1: 0   // correct
    // Test2:     // no exception, what? but it's null!
    //
    // If Test3 is allowed to run, we get:
    //   "Object reference not set to an instance of an object."

 It is odd that we can access Test2 when its value is null but we get no output string.

Microsoft's web site correctly describes nullable types (http://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx):

"A nullable type can represent the correct range of values for its underlying value type, plus an additional null value."

But most of us gloss over descriptions like that and until you see it demonstrated, you may not truly understand.

I hope someone finds this useful, Steve Wellens.

3 Comments

  • If you declare
    Nullable&lt;int&gt; foo;
    and then r-click and go to the definition of Nullable you'll see it overriding ToString(). If you expand the comments, you'll see this subtlety explained. This isn't shown in the help or on MSDN as far as I can see.
    In live code, I'd expect to see the output line guarded by a Test2.HasValue condition.
    \m

  • To me, the subtlety is that the variable can be "null" but you can still reference it's functions.

  • The subtlety stems from Nullable being a struct, not a class.

Comments have been disabled for this content.