Tipi di valori nullable (Visual Basic)

A volte si lavora con un tipo di valore che non ha un valore definito in determinate circostanze. Ad esempio, un campo di un database potrebbe dover distinguere tra avere un valore assegnato significativo e non avere un valore assegnato. I tipi valore possono essere estesi per accettare i valori normali o un valore Null. Tale estensione è detta tipo nullable.

Ogni tipo di valore che ammette i valori Null viene creato dalla struttura generica Nullable<T>. Si consideri un database che tiene traccia delle attività correlate al lavoro. L'esempio seguente crea un tipo nullable Boolean e dichiara una variabile di tale tipo. È possibile scrivere la dichiarazione in tre modi:

Dim ridesBusToWork1? As Boolean
Dim ridesBusToWork2 As Boolean?
Dim ridesBusToWork3 As Nullable(Of Boolean)

La variabile ridesBusToWork può contenere un valore True, un valore False o nessun valore. Il valore predefinito iniziale non è un valore, il che in questo caso potrebbe significare che le informazioni per questa persona non sono state ancora ottenute. Al contrario, False potrebbe significare che le informazioni sono state ottenute e che la persona non va a lavorare in autobus.

È possibile dichiarare variabili e proprietà con tipi di valori che ammettono i valori Null ed è possibile dichiarare una matrice con elementi di questo tipo. È possibile dichiarare routine con tipi di valori che ammettono i valori Null come parametri ed è possibile restituire un tipo valore che ammette i valori Null da una routine Function.

Non è possibile creare un tipo nullable per un tipo di riferimento, ad esempio una matrice, un oggetto String o una classe. Il tipo sottostante deve essere un tipo valore. Per altre informazioni, vedere Value Types and Reference Types.

Uso di una variabile di tipo nullable

I membri più importanti di un tipo di valore che ammette i valori Null sono le relative proprietà HasValue e Value. Per una variabile di un tipo di valore che ammette i valori Null, HasValue indica se la variabile contiene un valore definito. Se HasValue è True, è possibile leggere il valore da Value. Si noti che sia HasValue che Value sono proprietà ReadOnly.

Valori predefiniti

Quando si dichiara una variabile con un tipo di valore che ammette i valori Null, la relativa proprietà HasValue ha un valore predefinito False. Questo significa che per impostazione predefinita la variabile non ha alcun valore definito, neanche il valore predefinito del tipo valore sottostante. Nell'esempio seguente la variabile numberOfChildren inizialmente non ha alcun valore definito, anche se il valore predefinito del tipo Integer è 0.

Dim numberOfChildren? As Integer

Un valore Null è utile per indicare un valore non definito o sconosciuto. Se numberOfChildren venisse dichiarata come Integer, non esisterebbe alcun valore che potrebbe indicare che le informazioni non sono attualmente disponibili.

Archiviazione dei valori

Un valore in una variabile o in una proprietà di un tipo di valore che ammette i valori Null viene archiviato nel modo consueto. L'esempio seguente assegna un valore alla variabile numberOfChildren dichiarata nell'esempio precedente.

numberOfChildren = 2

Se una variabile o una proprietà di un tipo di valore che ammette i valori Null contiene un valore definito, è possibile ripristinarne lo stato iniziale senza un valore assegnato. A tale scopo, impostare la variabile o la proprietà su Nothing, come illustrato nell'esempio seguente.

numberOfChildren = Nothing

Nota

Sebbene sia possibile assegnare Nothing a una variabile di un tipo di valore che ammette i valori Null, non è possibile testarla per verificare la presenza di Nothing usando il segno di uguale. Il confronto che usa il segno di uguale, someVar = Nothing, restituisce sempre Nothing. È possibile testare la proprietà HasValue della variabile per verificare se è False o usando l'operatore Is o IsNot.

Recupero di valori

Per recuperare il valore di una variabile di un tipo di valore che ammette i valori Null, è necessario prima testare la relativa proprietà HasValue per verificare che abbia un valore. Se si tenta di leggere il valore quando HasValue è False, Visual Basic genera un'eccezione InvalidOperationException. L'esempio seguente illustra il modo consigliato per leggere la variabile numberOfChildren degli esempi precedenti.

If numberOfChildren.HasValue Then
    MsgBox("There are " & CStr(numberOfChildren) & " children.")
Else
    MsgBox("It is not known how many children there are.")
End If

Confronto di tipi nullable

Quando le variabili nullable Boolean vengono usate nelle espressioni booleane, il risultato può essere True, False o Nothing. Di seguito è riportata la tabella di verità per And e Or. Poiché b1 e b2 ora hanno tre valori possibili, esistono nove combinazioni da valutare.

b1 b2 b1 AND b2 b1 OR 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

Quando il valore di una variabile booleana o di un'espressione è Nothing, non è né truefalse. Si consideri l'esempio seguente.

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

In questo esempio b1 And b2 restituisce Nothing. Di conseguenza, la clausola Else viene eseguita in ogni istruzione If e l'output è il seguente:

Expression is not true

Expression is not false

Nota

AndAlso e OrElse, che usano la valutazione di cortocircuito, devono valutare i secondi operandi quando il primo restituisce Nothing.

Propagazione

Se uno o entrambi gli operandi di un'operazione aritmetica, di confronto, di spostamento o di tipo è un tipo di valore che ammette i valori Null, anche il risultato dell'operazione è un tipo di valore che ammette i valori Null. Se entrambi gli operandi hanno valori diversi da Nothing, l'operazione viene eseguita sui valori sottostanti degli operandi, come se nessuno dei due fosse un tipo di valore che ammette i valori Null. Nell'esempio seguente le variabili compare1 e sum1 vengono tipizzate in modo implicito. Se si posiziona il puntatore del mouse su di esse, si noterà che il compilatore deduce i tipi di valori che ammettono valori Null per entrambe.

' 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}")

Se uno o entrambi gli operandi hanno un valore Nothing, il risultato sarà 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>")}")

Uso di tipi nullable con dati

Un database è una delle risorse più importanti in cui usare tipi di valori che ammettono i valori Null. Non tutti gli oggetti di database supportano attualmente i tipi di valori che ammettono i valori Null, ma gli adattatori di tabella generati dalla finestra di progettazione li supportano. Vedere Supporto di TableAdapter per i tipi nullable.

Vedi anche