Recipe4.7.Creating a Value Type That Can Be Initialized to Null


Recipe 4.7. Creating a Value Type That Can Be Initialized to Null

Problem

You have a variable that is a numeric type, which will hold a numeric value obtained from a database. The database may return this value as a null. You need a simple clean way to store this numeric value, even if it is returned as a null.

Solution

Use a nullable value type. There are two ways of creating a nullable value type. The first way is to use the ? type modifier:

 int? myDBInt = null; 

The second way is to use the Nullable<T> generic type:

 Nullable<int> myDBInt = new Nullable<int>(); 

Discussion

Essentially both of the following statements are equivalent:

 int? myDBInt = null; Nullable<int> myDBInt = new Nullable<int>(); 

In both cases, myDBInt is considered a nullable type and is initialized to null. A nullable type implements the INullableValue interface, which has two read-only property members, HasValue and Value. The HasValue property returns false if the nullable type is set to null; otherwise it returns true. If HasValue returns TRue, you can access the Value property, which contains the currently stored value in the nullable data type. If HasValue returns false and you attempt to read the Value property, you will get an InvalidOperationException tHRown. This is because the Value property is undefined at this point.

In addition, testing the nullable type can be done in one of two ways. First, by using the HasValue property as shown here:

 if (myDBInt.HasValue)     Console.WriteLine("Has a value: " + myDBInt.Value); else     Console.WriteLine("Does not have a value (NULL)"); 

and, second, by comparing it to null:

 if (myDBInt != null)     Console.WriteLine("Has a value: " + myDBInt.Value); else     Console.WriteLine("Does not have a value (NULL)"); 

Either method is acceptable.

When casting a nullable type to a non-nullable type, the cast operates as it would normally, except when the nullable type is set to null. In this case, an InvalidOperationException is thrown. When casting a non-nullable type to a nullable type, the cast operates as it would normally. No InvalidOperationException will be thrown, as the non-nullable type can never be null.

The tricky thing to watch out for with nullable types is when comparisons are performed. For example if the following code is executed:

 if (myTempDBInt < 100)     Console.WriteLine("myTempDBInt < 100"); else     Console.WriteLine("myTempDBInt >= 100"); 

The text "myTempDBInt >= 100" is displayed, which is obviously incorrect. To fix this code, you have to check if myTempDBInt is null. If it is not, you can execute the if statement in the previous code block:

 if (myTempDBInt != null) {     if (myTempDBInt < 100)         Console.WriteLine("myTempDBInt < 100");     else         Console.WriteLine("myTempDBInt >= 100"); } else {     // Handle the null here. } 

Another interesting thing about nullable types is that you can use them in expressions similar to normal numeric types, for example:

 int? DBInt = 10; int Value = 2; int? Result = DBInt + Value; // Result == 12 

The result of using a nullable type in an expression is a null if any nullable type is null. However, if none of the nullable types is null, the operation is evaluated as it normally would be. If DBInt, for example, is set to null, the value placed in Result will also be null.

See Also

See the "Nullable<T> Generic Class" and "Using Nullable Types" topics in the MSDN documentation.



C# Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2004
Pages: 424

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net