Mihir Solanki

mihirsolanki.com

<November 2008>
SuMoTuWeThFrSa
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456


Navigation

Links

Subscriptions

Post Categories



.NET Framework FAQ : What Are Nullable Types?

Unlike reference types, you cannot assign a null into a value type. This is often a problem when interacting with code that interprets a null as having no value, rather than no-reference. The canonical example is database null values in columns that have representation as types such as int or DateTime. To address that, the System namespace provides the structure Nullable defined as:

public interface INullableValue 
{ 
   bool HasValue{get;} 
   object Value{get;} 
} 
[Serializable] 
public struct Nullable : INullableValue,IEquatable>,... where T : struct 
{ 
   public Nullable(T value); 
   public bool HasValue{get;} 
   public T Value{get;} 
   public T GetValueOrDefault(); 
   public T GetValueOrDefault(T defaultValue); 
   public bool Equals(Nullable other);    
   public static implicit operator Nullable(T value); 
   public static explicit operator T(Nullable value); 

   //More members 
}

Because the Nullable struct uses a generic type parameter, you can use it to wrap a value type, and assign null into it:

Nullable<int> number = 123; 
Debug.Assert(number.HasValue); 
number = null; 
Debug.Assert(number.HasValue == false); 
Debug.Assert(number.Equals(null));

Once a null is assigned to a nullable type, you can still access it to verify if it has a value, via the HasValue property, or just equate it to null.

In C# and Visual Basic, you can even use the underlying value type's operators on a nullable type:

Nullable<int> number = 0; 
number++;

The reason this is possible is because the compiler is capable of verifying that the underlying type supported the operator, and applying it on the value stored in the structure. This is called lifted operators.

The Nullable struct also provides conversion operators, so you can convert a nullable type to and from a real value type:

Nullable<int> nullableNumber = 123; 
int number = (int)nullableNumber; 
Debug.Assert(number == 123); 

number = 456; 
nullableNumber = number; 
Debug.Assert(nullableNumber.Equals(456));

Note that using Nullable on Nullable is disallowed, and the compiler will issue an error:

//This will not compile: 
Nullable<Nullable<int>> number = 123;

You can use the overloaded methods GetValueOrDefault() of Nullable to defensively obtain either the value stored in the nullable type or it its default, if it does contain a null:

Nullable<DateTime> time = null; 
DateTime value = time.GetValueOrDefault(); 
Debug.Assert(value.ToString() == "1/1/0001 12:00:00 AM");

The System namespace also defines the static helper class Nullable and the helper class NullableConverter, but those are not needed usually.

The C# 2.0 compiler supports shorthand for Nullable. You can use the ? modifier on value types to actually construct a Nullable around it:

int? number = 123; 
Debug.Assert(number.HasValue); 
number = null; 
Debug.Assert(number.HasValue == false);

Note that the type declared by the ? modifier is identical to that created using Nullable directly:

Debug.Assert(typeof(int?) == typeof(Nullable<int>));

As with using Nullable directly, the compiler supports lifted operators. Whenever you combine nullable types using operators, if any one of them is null, then the resulting expression will be null too:

int? number1 = 123; 
int? number2 = null; 
int? sum = number1 + number2; 
Debug.Assert(sum == null);

Using the ? modifier is the common way of declaring and using nullable variables in C#. You can even pass nullable types as type arguments for generic types:

IList<int?> list = new List<int?>(); 
list.Add(3); 
list.Add(null);

C# 2.0 also provides the null coalescing operator via the ?? operator.

c = a ?? b;

The result of applying the ?? operator on two operands returns the left hand side operand (a) if it is not null, and the right operand (b)otherwise. While b can of course be null too, you typically use the ?? operator to supply a default value in case a is null.

Summary

  • 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, 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 method 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;

Source : MSDN

posted on Tuesday, December 27, 2005 6:22 PM by mihirsolanki





Powered by Dot Net Junkies, by Telligent Systems