Monthly Archives: October 2010

Nullable types

In programming, nullable types are a feature of some statically-typed programming languages which allows a data type to be set to the special value NULL instead of their common range of possible values. For value types or built-in data types like integers and booleans however, such behavior is mostly not possible. Nullable type support allows for the programmer to make also these value types NULL. This can be useful in general and also when working with databases. A field in a Relational database like SQL may have an entry that is NULL (or empty) instead of containing a value. A language with nullable type support can then return a NULL value and correctly represent the behavior of the database. In programming languages like C# 2.0 a Nullable integer for example can be declared by a question mark (int? x)

Database columns can have value as NULL or the column value is blank. This is a common problem when writing code to access database column data. The data might be null, blank or filled with some data. So languages like C#, support the null type. Nullable types are value types which are wrappers round other value types , allowing a "null value" to be represented. They are particularly useful with database code, as databases often have nullable columns for numbers, dates and times, GUIDs etc – all of which are value types in .NET. The Nullable<T> structure is at the heart of nullable types, and C# has extra syntactic sugar with the "?" modifier. For example:

   1: using System;

   2: using System.Collections.Generic;

   3: using System.Linq;

   4: using System.Text;

   5:  

   6: namespace ConsoleApplication1

   7: {

   8:     class Program

   9:     {

  10:         static void Main(string[] args)

  11:         {

  12:             // x, y and z are the same type

  13:             int? x = null;

  14:             Nullable<int> y = 10;

  15:  

  16:             int? z = x + y;

  17:  

  18:             if (y == null)

  19:             {

  20:                 Console.WriteLine("Null result");

  21:             }

  22:             else

  23:             {

  24:                 // Note: not nullable

  25:                 int result = y.Value;

  26:                 Console.WriteLine("Result: {0}", result);

  27:             } 

  28:  

  29:         }

  30:     }

  31: }

  • The CLR knows about nullable types too – it makes sure that if you box the null value of a nullable type, you end up with a null reference. (And likewise you can unbox a null reference to the null value of a nullable type.)
  • How operators work with nullable types is a language decision. For instance, comparing two int? values for equality always gives true or false in C#; in VB.NET it can result in null (if either side is null). Be careful when porting code!

The null coalescing operator can be used with reference types, and the right hand side can also be a reference type or a nullable type. It can be useful to use the operator several times in a row, e.g. first ?? second ?? third. Indeed, the language is designed to enable this to work exactly how you’d like it to. A value type constraint explicitly excludes any nullable types.

Nullable types have the following characteristics (very useful MSDN article):

  • Nullable types represent value-type variables that can be assigned the value of null. You cannot create a nullable type based on a reference type. (Reference types already support the null value.)

  • The syntax T? is shorthand for System.Nullable<T>, where T is a value type. The two forms are interchangeable.

  • Assign a value to a nullable type in the same way as for an ordinary value type, for example int? x = 10; or double? d = 4.108;

  • Use the System.Nullable.GetValueOrDefault property to return either the assigned value, or the default value for the underlying type if the value is null, for example int j = x.GetValueOrDefault();

  • Use the HasValue and Value read-only properties to test for null and retrieve the value, for example if(x.HasValue) j = x.Value;

    • The HasValue property returns true if the variable contains a value, or false if it is null.

    • The Value property returns a value if one is assigned, otherwise a System.InvalidOperationException is thrown.

    • The default value for a nullable type variable sets HasValue to false. The Value is undefined.

  • Use the ?? operator to assign a default value that will be applied when a nullable type whose current value is null is assigned to a non-nullable type, for example int? x = null; int y = x ?? -1;

  • Nested nullable types are not allowed. The following line will not compile: Nullable<Nullable<int>> n;

    The difference between the impossible and possible lies in a person’s determination.