Null and Nullable Types
These default values mean that a value type cannot be null, which at first glance might seem reasonable. However, it presents certain limitations when you work with databases, other external data sources, or other data types that can contain elements that might not be assigned a value. A classic example of this is a numeric field in a database that can store any integer data or might be undefined.
Nullable types provide a solution to this problem. A nullable type is a value type that can represent the proper value range of its underlying type and a null value. Nullable types are represented by the syntax Nullable<T> or T? where T is a value type. The preferred syntax is T?. You assign a value to a nullable type just as you would a non-nullable type:
int x = 10; int? x = 10; int? x = null;
To access the value of a nullable type, you should use the GetValueOrDefault method, which returns the assigned value, or, if the value is null, the default value for the underlying type. You can also use the HasValue property, which returns true if the variable contains an actual value, and the Value property, which returns the actual value or results in an exception if the value is null.
All nullable types, including reference types, support the null-coalescing operator (??), which defines the default value to be returned when a nullable type is assigned to a non-nullable type. If the left operator is null, the right operator is returned; otherwise, the left operator is returned. Listing 3.4 shows how the null-coalescing operator can be used.
Listing 3.4. Null-Coalescing Operator
int? x = null; Console.WriteLine(x ?? -1); x = 3; Console.WriteLine(x ?? -1); string s = null; Console.WriteLine(s ?? "Undefined");