可為 Null 的實值類型 (Visual Basic)
有時會在特定情況下使用不具有已定義值的實值型別。 例如,資料庫中的欄位可能需要在已指派有意義值與未指派值之間加以區別。 實值型別可擴充為接受一般值或 null 值。 這類擴充稱為「可為 Null 的型別」(Nullable Type)。
每個可為 Null 的型別是從泛型 Nullable 結構建構而來。 請考慮會追蹤工作相關活動的資料庫。 下列範例會建構可為 Null 的 Boolean 型別,並宣告該型別的變數。 您可以用下列三種方法撰寫宣告:
Dim ridesBusToWork1? As Boolean
Dim ridesBusToWork2 As Boolean?
Dim ridesBusToWork3 As Nullable(Of Boolean)
變數 ridesBusToWork 可存放 True 值、False 值或根本沒有值。 初始預設值是「根本沒有值」,在這個情況下,表示尚未取得這個人的資訊。 相較之下,False 表示已取得資訊,且那個人未搭乘公車上班。
您可以宣告具有可為 Null 之型別的變數和屬性 (Property),而且可以宣告具有可為 Null 之型別的元素陣列。 也可以將具有可為 Null 型別的程序宣告為參數,並從 Function 程序傳回可為 Null 的型別。
但無法在參考型別 (Reference Type) 上建構可為 Null 的型別 (例如陣列、String 或類別 (Class))。 基礎型別必須是實值型別。 如需詳細資訊,請參閱 實值類型和參考類型。
使用可為 Null 型別的變數
可為 Null 型別的最重要成員是它的 HasValue 和 Value 屬性。 如果是可為 Null 型別的變數,則 HasValue 會告知您變數是否包含已定義值。 如果 HasValue 為 True,則可以從 Value 中讀取值。 請注意,HasValue 和 Value 都是 ReadOnly 屬性。
預設值
宣告具有可為 Null 型別的變數時,HasValue 屬性的預設值為 False。 這表示變數依預設沒有已定義值,而非基礎實值型別的預設值。 在下列範例中,即使 Integer 型別的預設值為 0,變數 numberOfChildren 一開始也不會有已定義值。
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 例外狀況 (Exception)。 下列範例會顯示讀取先前範例之變數 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 的型別
當可為 Null 的 Boolean 變數用於 Boolean 運算式時,結果可以是 True、False 或 Nothing。 下列是 And 和 Or 的事實資料表。 因為 b1 和 b2 現在有 3 個可能值,所以共有 9 個組合要評估。
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。 因此會在每個 If 陳述式 (Statement) 中執行 Else 子句,輸出如下:
Expression is not true
Expression is not false
注意事項 |
---|
AndAlso 和 OrElse 使用「最少運算」(Short-Circuit) 評估,必須在第一個運算元評估為 Nothing 時評估第二個運算元。 |
傳用
如果算術、比較、移位或型別運算的其中一個或兩個運算元可為 Null,則該運算的結果也可為 Null。 如果兩個運算元都有非 Nothing 的值,則運算會在運算元的基礎值上執行,如同它們都不是可為 Null 的型別。 在下列範例中,變數 compare1 和 sum1 是隱含型別的。 如果您將滑鼠指標停留在上面,就會看到編譯器推斷兩者都是可為 Null 的型別。
' 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 * * *
Console.WriteLine(m & " * " & n & " * " & sum2 & " * " & compare2)
搭配使用可為 Null 的型別與資料
資料庫是使用可為 Null 之型別的其中一個最重要位置。 並非所有資料庫物件目前都支援可為 Null 的型別,而設計工具產生的資料表配接器則會支援該型別。 請參閱 TableAdapter 概觀中的<TableAdapter 支援可為 Null 的型別>。