通过向变量声明添加(of Type)类型参数,.NET Framework 2.0可向VB.NET 2005添加泛型类型。Nullable变量是泛型类型的扩展,它可以使值类型(Inter、Int16、Decimal、Data、DataTime等)支持空值。将Nothing赋给值类型会返回该类型的默认值:数字类型返回0,日期类型返回01/01/0001 12:00:00。
如果用Nullable(of Type)代替值类型数据类型标识符,可以使空值有效。引用类型(如String)本身支持空值,因此不需要添加Nullable(of String)。Nullable变量的最有用的应用是方法签名。在方法签名中,采用Nullable值类型可避免重载。例如,在Northwind Order表中通过类型化DataSet插入一个新行时,一般需要如下所示的两个Insert方法签名和对应的两个Overload函数。
Function Insert(ByVal CustomerID As String,
ByVal EmployeeID As Integer, _
ByVal OrderDate As Date, _
ByVal RequiredDate As Date, _
ByVal ShippedDate As Date, _
ByVal ShipVia As Integer,
ByVal Freight As Decimal,
ByVal ShipName As String, _
ByVal ShipAddress As String,
ByVal ShipCity As String, _
ByVal ShipRegion As String,
ByVal ShipPostalCode As String, _
ByVal ShipCountry As String) As Integer
Function Insert(ByVal CustomerID As Object,
ByVal EmployeeID As Object, _
ByVal OrderDate As Object,
ByVal RequiredDate As Object, _
ByVal ShippedDate As Object, _
ByVal ShipVia As Object, _
ByVal Freight As Object, _
ByVal ShipName As Object, _
ByVal ShipAddress As Object, _
ByVal ShipCity As Object, _
ByVal ShipRegion As Object, _
ByVal ShipPostalCode As Object, _
ByVal ShipCountry As Object) As Integer
如果所有的值均存在,则第一个方法签名有效。如果传递给函数的任一值类型为空,则需要第二个非类型化签名。在这种情况下,用户的代码可提供一个String值来代替Integer值或Decimal值。向值类型添加Nullable(Of Type)后,可以使单个的函数处理空值类型,如下面的代码所示。
Function Insert(ByVal CustomerID As String, _
ByVal EmployeeID As Nullable(Of Integer), _
ByVal OrderDate As Nullable(Of Date), _
ByVal RequiredDate As Nullable(Of Date), _
ByVal ShippedDate As Nullable(Of Date), _
ByVal ShipVia As Nullable(Of Integer), _
ByVal Freight As Nullable(Of Decimal), _
ByVal ShipName As String, _
ByVal ShipAddress As String, _
ByVal ShipCity As String, _
ByVal ShipRegion As String, _
ByVal ShipPostalCode As String, _
ByVal ShipCountry As String) As Integer
设置与Nullable类型对应的INSERT或UPDATE参数值时,需要通过HasValue属性测试指定值是否存在。如果HasValue为True,则传递Value属性,如下面使用INSERT命令的代码段所示。代码中用INSERT命令添加所需要的参数。
...
Me.InsertCommandParameters(0).Value = CustomerID
If EmployeeID.HasValue Then
Me.InsertCommandParameters(1).Value = EmployeeID.Value
Else
Me.InsertCommandParameters(1).Value = DBNull.Convert
End If
If OrderDate.HasValue Then
Me.InsertCommandParameters(2).Value = OrderDate.Value
Else
Me.InsertCommandParameters(2).Value = DBNull.Convert
End If
If RequiredDate.HasValue Then
Me.InsertCommandParameters(3).Value = RequiredDate.Value
Else
Me.InsertCommandParameters(3).Value = DBNull.Convert
End If
If ShippedDate.HasValue Then
Me.InsertCommandParameters(4).Value = ShippedDate.Value
Else
Me.InsertCommandParameters(4).Value = DBNull.Convert
End If
...
由于基表外键的约束,不需要为不能为空的变量指定Nullable类型,就如前面示例中的EmployeeID所示。对于承受业务规则的变量也是如此。例如,每一个订单均需要一个OrderData值。
用户还可以将Nullable(Of Type)应用于Public或Private类成员。下面是一个有映射到Northwind Order表字段的Public属性的简单业务对象的示例。通过业务规则和外键约束来决定哪些字段是Nullable。本例为RequiredData、ShippedDate、Freight、ShipRegion以及ShipPostalCode。ShipRegion和ShipPostalCode是引用类型,它们均被定义为Nullable。
Public Class Orders
Public OrderID As Integer
Public CustomerID As String
Public EmployeeID As Integer
Public OrderDate As Date
Public RequiredDate As Nullable(Of Date)
Public ShippedDate As Nullable(Of Date)
Public ShipVia As Integer
Public Freight As Nullable(Of Decimal)
...
Public ShipCountry As String
End Class
以下是前面所介绍类的简化形式,它通过Get和Set访问器使用私有成员。
Public Class Orders
Private m_OrderID As Integer
Public Property OrderID() As Integer
Get
Return m_OrderID
End Get
Set(ByVal value As Integer)
m_OrderID = value
End Set
End Property
...
Private m_RequiredDate As Nullable(Of Date)
Public Property RequiredDate() As Nullable(Of Date)
Get
Return m_RequiredDate
End Get
Set(ByVal value As Nullable(Of Date))
m_RequiredDate = value
End Set
End Property
Private m_ShippedDate As Nullable(Of Date)
Public Property ShippedDate() As Nullable(Of Date)
Get
Return m_ShippedDate
End Get
Set(ByVal value As Nullable(Of Date))
m_ShippedDate = value
End Set
End Property
...
Private m_Freight As Nullable(Of Decimal)
Public Property Freight() As Nullable(Of Decimal)
Get
Return m_Freight
End Get
Set(ByVal value As Nullable(Of Decimal))
m_Freight = value
End Set
End Property
...
Private m_ShipCountry As String
Public Property ShipCountry() As String
Get
Return m_ShipCountry
End Get
Set(ByVal value As String)
m_ShipCountry = value
End Set
End Property
End Class
指定Nullable类成员并使用HasValue和Value属性等价于用If ReferenceType Is Noting Then … 或If ValueType=Nothing Then…来测试指定的属性值。示例项目NullableTypes.sln利用由SqlDataReader填充的对象为Order表测试了这两种方法。