Using Nullable Types (2)

Nullable types can represent all the values of an underlying type, and an additional null value. Nullable types are declared in one of two ways:

System.Nullable<T> variable

-or-   

T? variable

T is the underlying type of the nullable type. T can be any value type including struct; it cannot be a reference type.

For an example of when you might use a nullable type, consider how an ordinary Boolean variable can have two values: true and false. There is no value that signifies "undefined". In many programming applications, most notably database interactions, variables can exist in an undefined state. For example, a field in a database may contain the values true or false, but it may also contain no value at all. Similarly, reference types can be set to null to indicate that they are not initialized.

This disparity can create extra programming work, with additional variables used to store state information, the use of special values, and so on. The nullable type modifier enables C# to create value-type variables that indicate an undefined value.

Examples of Nullable Types

Any value type may be used as the basis for a nullable type. For example:

int? i = 10;

double? d1 = 3.14;

bool? flag = null;

char? letter = 'a';

int?[] arr = new int?[10];

The Members of Nullable Types

Each instance of a nullable type has two public read-only properties:

·       HasValue

HasValue is of type bool. It is set to true when the variable contains a non-null value.

·       Value

Value is of the same type as the underlying type. If HasValue is true, Value contains a meaningful value. If HasValue is false, accessing Value will throw a InvalidOperationExc eption.

In this example, the HasValue member is used to test if the variable contains a value before attempting to display it.

int? x = 10;

if (x.HasValue)

{

    System.Console. WriteLine( x.Value);

}

else

{

    System.Console. WriteLine("Undefined");

}

Testing for a value can also be done like this:

int? y = 10;

if (y != null)

{

    System.Console. WriteLine( y.Value);

}

else

{

    System.Console. WriteLine("Undefined");

}

Explicit Conversions

A nullable type can be cast to a regular type, either explicitly with a cast, or by using the Value property. For example:

int? n = null;

//int m1 = n;      // Will not compile.

int m2 = (int)n;   // Compiles, but will create an exception if x is null.

int m3 = n.Value;  // Compiles, but will create an exception if x is null.

If a user-defined conversion is defined between two data types, the same conversion can also be used with the nullable versions of these data types.

Implicit Conversions

A variable of nullable type can be set to null with the null keyword, as shown below:

int? n1 = null;

The conversion from an ordinary type to a nullable type, is implicit.

int? n2;

n2 = 10;  // Implicit conversion.

Operators

The predefined unary and binary operators and any user-defined operators that exist for value types may also be used by nullable types. These operators produce a null value if the operands are null; otherwise, the operator uses the contained value to calculate the result. For example:

int? n2;

n2 = 10;  // Implicit conversion.

When performing comparisons with nullable types, if either of the nullable types is null, the comparison is always evaluated to be false. It is therefore important not to assume that because a comparison is false, the opposite case is true. For example:

int? a = 10;

int? b = null;

a++;         // Increment by 1, now a is 11.

a = a * 10;  // Multiply by 10, now a is 110.

a = a + b;   // Add b, now a is null.

The conclusion in the else statement above is not valid because num2 is null and therefore doesn't contain a value.

The ?? Operator

The ?? operator defines a default value that is returned when a nullable type is assigned to a non-nullable type.

int? e = null;

int? f = null;

// g = e or f, unless e and f are both null, in which case g = -1.

int g =  e ?? f ?? -1;

This operator can also be used with multiple nullable types. For example:

int? e = null;

int? f = null;

// g = e or f, unless e and f are both null, in which case g = -1.

int g =  e ?? f ?? -1;

The bool? type

The bool? nullable type can contain three different values: true, false and null. As such, they cannot be used in conditionals such as with if, for, or while. For example, this code fails to compile with Compiler Error CS0266.

bool? b = null;

if (b) // Error CS0266.

{

}

This is not allows because it is unclear what null means in the context of a conditional. Nullable Booleans can be cast to a bool explicitly in order to be used in a conditional, but if the object has a value if null, InvalidOperationExc eption will be thrown. It is therefore important to check the HasValue property before casting to bool.

Nullable Booleans are similar to the Boolean variable type used in SQL. To ensure that the results produced by the & and | operators are consistent with SQL's three-valued Boolean type, the following predefined operators are provided:

bool? operator &(bool? x, bool? y)

bool? operator |(bool? x, bool? y)

The results of these operators are listed in the table below:

X       y       x&y     x|y    
True    true    True    true   
True    false   False   true   
True    null    Null    true   
False   true    False   true   
False   false   False   false  
False   null    False   null   
Null    true    Null    true   
Null    false   False   null   
Null    null    Null    null   

Source: http://msdn2. microsoft. com/en-us/ library/2cf62fcy .aspx

Next Recommended Reading Data types in SQL Server 2000