2.6. Make Simple Data Types Nullable
With the new support for generics
that's found in the .NET Framework, a number of new
features become possible. One of these featuresgeneric
strongly typed collectionswas demonstrated in the previous
lab, "Build Typesafe Generic
Classes." Now you'll see another
way that generics can solve common problems, this time by using the
new nullable data types.
Note: Do you need to represent data that may or may not be
present? VB . NET's new nullable types fill the
gap.
2.6.1. How do I do that?
A null value (identified in Visual Basic by the keyword
Nothing), is a special flag that indicates no data
is present. Most developers are familiar with null object references,
which indicate that the object has been defined but not created. For
example, in the following code, the FileStream
contains a null reference because it hasn't been
instantiated with the New keyword:
Dim fs As FileStreamCore data types like integers and strings
If fs Is Nothing
' This is always true because the FileStream hasn't
' been created yet.
Console.WriteLine("Object contains a null reference.")
End If
can't contain null values.
Numeric variables are automatically initialized to
0. Boolean variables are False.
String variables are set to an empty string (''") automatically. In
fact, even if you explicitly set a simple data type variable to
Nothing in your code, it will automatically revert
to the empty value (0, False,
or "), as the following code demonstrates:
Dim j As Integer = NothingThis design sometimes causes problems, because
If j = 0 Then
' This is always true because there is an
' implicit conversion between Nothing and 0 for integers.
Console.WriteLine("Non-nullable integer j = " & j)
End If
there's no way to distinguish between an empty value
and a value that was never supplied in the first place. For example,
imagine you create code that needs to retrieve the number of times
the user has placed an order from a text file. Later on, you examine
this value. The problem occurs if this value is 0.
Quite simply, you have no way to know whether this is valid data (the
user placed no orders), or it represents missing information (the
setting couldn't be retrieved or the current user
isn't a registered customer).Thanks to generics, .NET 2.0 has a solutiona
System.Nullable class
that can wrap any other data type. When you create an instance of
Nullable you specify the data type. If you
don't set a value, this instance contains a null
reference. You can test whether this is true by testing the
Nullable.HasType( ) method, and you can retrieve
the underlying object through the Nullable.Value
property.Here's the sample code you need to create a nullable
integer:
Dim i As Nullable(Of Integer)
If Not i.HasValue Then
' This is true, because no value has been assigned.
Console.WriteLine("i is a null value")
End If
' Assign a value. Note that you must assign directly to i, not i.Value.
' The i.Value property is read-only, and it always reflects the
' currently assigned object, if it is not Nothing.
i = 100
If i.HasValue Then
' This is true, because a value (100) is now present.
Console.WriteLine("Nullable integer i = " & i.Value)
End If
2.6.2. What about...
...using Nullable
with full-fledged reference objects? Although you
don't need this ability (because reference types can
contain a null reference), it still gives you some advantages.
Namely, you can use the slightly more readable HasValue() method instead of testing for Nothing.
Best of all, you can make this change seamlessly, because the
Nullable class has the remarkable ability to allow
implicit conversions between Nullable and the type
it wraps.
2.6.3. Where can I learn more?
To learn more about Nullable and how
it's implemented, look up the
"Nullable class" index entry in the
MSDN Help.