有時候,您會使用在某些情況下沒有已定義值的實值型別。 例如,資料庫中的欄位可能必須區分有指派有意義的值與沒有指派值的狀況。 實值型別可以擴充為採用其一般值或 Null 值。 這類延伸模組稱為 可空值類型。
每個可為 Null 的實值類型都是從泛型 Nullable<T> 結構建構。 請考慮追蹤工作相關活動的資料庫。 下列範例會建構可為 null 的Boolean
類型,並宣告該類型的變數。 您可以透過三種方式撰寫宣告:
Dim ridesBusToWork1? As Boolean
Dim ridesBusToWork2 As Boolean?
Dim ridesBusToWork3 As Nullable(Of Boolean)
變數ridesBusToWork
可以保留值True
、值False
或完全不保留任何值。 其初始預設值完全為空,這在此案例中可能表示尚未取得此人的資訊。 相比之下, False
可能意味著已經取得資訊,而且該人員不會乘坐公共汽車上班。
您可以使用可為 Null 的值型別來宣告變數和屬性,並且可以使用可為 Null 的值型別的元素來宣告陣列。 您可以宣告具有可為 Null 實值類型的參數的程式,而且可以從 Function
程式傳回可為 Null 的實值類型。
您無法在參考型別上建構可為 Null 的類型,例如陣列、 String
或類別。 基礎類型必須是實值型別。 如需詳細資訊,請參閱 實值型別和參考型別。
使用可為 Null 的類型變數
可為 Null 的實值類型最重要的成員是其 HasValue 和 Value 屬性。 針對可空值類型的變數,HasValue 告訴您變數是否包含已定義的值。 如果 HasValue 是 True
,您可以從 Value 讀取值。 請注意,HasValue 和 Value 都是 ReadOnly
屬性。
預設值
當您宣告具有可為 Null 實值類型的變數時,其 HasValue 屬性的預設值為 False
。 這表示變數預設沒有定義的值,而不是其基礎實值類型的預設值。 在下列範例中,變數 numberOfChildren
一開始沒有定義的值,即使類型的預設值 Integer
是 0。
Dim numberOfChildren? As Integer
Null 值可用來指出未定義或未知的值。 如果 numberOfChildren
已宣告為 Integer
,就沒有任何值可以表示資訊目前不可用。
儲存值
您可以使用一般方式,將值儲存在可為 Null 的值型變數或屬性中。 下列範例會將值指派給上一個範例中所宣告的變數 numberOfChildren
。
numberOfChildren = 2
如果可為 Null 的實值型別的變數或屬性包含已定義的值,您可以使其重置為未指派值的初始狀態。 若要這樣做,請將變數或屬性設定為 Nothing
,如下列範例所示。
numberOfChildren = Nothing
備註
雖然您可以將 Nothing
指派給可為 Null 值型別的變數,但您無法使用等號來測試 Nothing
。 使用等號 someVar = Nothing
的比較,一律會評估為 Nothing
。 您可以測試變數的 HasValue 屬性以檢查 False
,或是使用 Is
或 IsNot
運算子進行測試。
提取數值
若要擷取可為 Null 的值類型變數值,您應該先測試 HasValue 屬性,以確認它具有值。 當 HasValue 是 False
時,如果您嘗試讀取值,Visual Basic 會拋出 InvalidOperationException 例外狀況。 下列範例示範讀取先前範例變數 numberOfChildren
的建議方式。
If numberOfChildren.HasValue Then
MsgBox("There are " & CStr(numberOfChildren) & " children.")
Else
MsgBox("It is not known how many children there are.")
End If
比較可空類型
當布林運算式中使用可為 Null 的 Boolean
變數時,結果可以是 True
、 False
或 Nothing
。 以下是 And
和 Or
的真值表。 因為 b1
和 b2
現在有三個可能的值,因此有九個組合要評估。
b1 | b2 | b1 和 b2 | b1 或 b2 |
---|---|---|---|
Nothing |
Nothing |
Nothing |
Nothing |
Nothing |
True |
Nothing |
True |
Nothing |
False |
False |
Nothing |
True |
Nothing |
Nothing |
True |
True |
True |
True |
True |
True |
False |
False |
True |
False |
Nothing |
False |
Nothing |
False |
True |
False |
True |
False |
False |
False |
False |
當布林變數或表示式的值是 Nothing
時,它既不是 true
或 false
。 請考慮下列範例。
Dim b1? As Boolean
Dim b2? As Boolean
b1 = True
b2 = Nothing
' The following If statement displays "Expression is not true".
If (b1 And b2) Then
Console.WriteLine("Expression is true")
Else
Console.WriteLine("Expression is not true")
End If
' The following If statement displays "Expression is not false".
If Not (b1 And b2) Then
Console.WriteLine("Expression is false")
Else
Console.WriteLine("Expression is not false")
End If
在這裡範例中, b1 And b2
評估為 Nothing
。 因此, Else
子句會在每個 If
語句中執行,輸出如下所示:
Expression is not true
Expression is not false
備註
AndAlso
和 OrElse
使用短路求值,當第一個運算元的值為 Nothing
時,必須評估其第二個運算元。
增殖
如果算術、比較、位移或類型運算的一個或兩個運算元是可為 Null 的實值型別,則運算的結果也是可為 Null 的實值型別。 如果這兩個作數都有不是 Nothing
的值,則作業會在作數的基礎值上執行,就好像兩者都不是可為 Null 的實值類型一樣。 在下列範例中,變數 compare1
和 sum1
是隱含型別。 如果您將滑鼠指標懸停在它們上方,您會看到編譯器會推斷它們的可空值類型。
' Variable n is a nullable type, but both m and n have proper values.
Dim m As Integer = 3
Dim n? As Integer = 2
' The comparison evaluated is 3 > 2, but compare1 is inferred to be of
' type Boolean?.
Dim compare1 = m > n
' The values summed are 3 and 2, but sum1 is inferred to be of type Integer?.
Dim sum1 = m + n
' The following line displays: 3 * 2 * 5 * True
Console.WriteLine($"{m} * {n} * {sum1} * {compare1}")
如果一或兩個作數都有 的值 Nothing
,則結果會是 Nothing
。
' Change the value of n to Nothing.
n = Nothing
Dim compare2 = m > n
Dim sum2 = m + n
' Because the values of n, compare2, and sum2 are all Nothing, the
' following line displays: 3 * <null> * <null> * <null>
Console.WriteLine($"{m} * {If(n, "<null>")} * {If(sum2, "<null>")} * {If(compare2, "<null>")}")
搭配資料使用可空值類型
資料庫是使用可為空值型別最重要的地方之一。 並非所有資料庫物件目前都支援可為 Null 的值型別,但由設計工具生成的資料表適配器則支援。 請參閱 TableAdapter 對可為 Null 類型的支援。