可為 Null 的實值型別 (Visual Basic)

有時候,您會使用在特定情況下沒有定義值的實值型別。 例如,資料庫中的欄位可能必須區分具有有意義的指派值與沒有指派值。 實值型別可以擴充,以接受其一般值或 null 值。 此類延伸模組稱為「可為 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 或類別。 基礎類型必須是實值型別。 如需詳細資訊,請參閱 Value Types and Reference Types

使用可為 Null 的類型變數

可為 Null 實值型別最重要的成員是其 HasValueValue 屬性。 針對可為 Null 實值型別的變數,HasValue 會告訴您變數是否包含定義值。 若 HasValueTrue,您可以從 Value 讀取值。 請注意,HasValueValue 都是 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。 您可以使用 IsIsNot 運算子測試 False 變數的 HasValue 屬性。

擷取值

若要擷取可為 Null 實值型別的變數值,您應該先測試其 HasValue 屬性,以確認其具有值。 若您嘗試在 HasValueFalse 時讀取值,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 的類型

當布林運算式中使用可為 Null Boolean 變數時,結果可能會是 TrueFalseNothing。 下列是 AndOr 的真實資料表。 因為 b1b2 現在有三個可能的值,所以有九個組合可供評估。

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 時,其不是 truefalse。 請思考一下下列範例。

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

注意

AndAlsoOrElse,使用短線路評估時,當第一個運算元評估為 Nothing 時,必須評估其第二個運算元。

傳播

若算術、比較、移位或類型運算的一或兩個運算元都是可為 Null 的實值型別,則運算的結果也是可為 Null 實值型別。 若這兩個運算元都有不是 Nothing 的值,則運算會在運算元的基礎值上執行,就像兩者都不是可為 Null 的實值型別一樣。 在下列範例中,變數 compare1sum1 會隱含類型。 若您將滑鼠指標放在這些變數上,您會看到編譯器針對這兩者推斷可為 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 * <null> * <null> * <null>
Console.WriteLine($"{m} * {If(n, "<null>")} * {If(sum2, "<null>")} * {If(compare2, "<null>")}")

搭配資料使用可為 Null 的類型

資料庫是使用可為 Null 實值型別的最重要位置之一。 並非所有資料庫物件目前都支援可為 Null 的實值型別,但設計工具產生的資料表配接器支援。 請參閱 TableAdapter 支援可為 Null 的類型

另請參閱