Tipos de valor que permitem valor nulo (Visual Basic)

Às vezes, você trabalha com um tipo de valor que não tem um valor definido em determinadas circunstâncias. Por exemplo, um campo em um banco de dados pode ter que distinguir entre ter um valor atribuído que seja significativo e não ter um valor atribuído. Os tipos de valor podem ser estendidos para obter seus valores normais ou um valor nulo. Essa extensão é chamada de tipo que permite valor nulo.

Cada tipo de valor anulável é construído da estrutura genérica Nullable<T>. Considere um banco de dados que rastreia atividades relacionadas ao trabalho. O exemplo a seguir constrói um tipo que permite valor nulo Boolean e declara uma variável desse tipo. Você pode gravar a declaração de três maneiras:

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

A variável ridesBusToWork pode conter um valor de True, um valor de False ou nenhum valor. O valor padrão inicial dela é nenhum valor, o que, nesse caso, pode significar que as informações ainda não foram obtidas para essa pessoa. Por outro lado, False pode significar que as informações foram obtidas e que a pessoa não anda de ônibus para o trabalho.

Você pode declarar variáveis e propriedades com tipos de valor anuláveis e declarar uma matriz com elementos de um tipo de valor anulável. Você pode declarar procedimentos com tipos de valor anuláveis como parâmetros e pode retornar um tipo de valor anulável de um procedimento Function.

Você não pode construir um tipo que permite valor nulo em um tipo de referência, como uma matriz, uma String ou uma classe. O tipo subjacente precisa ser um tipo de valor. Para obter mais informações, consulte Tipos de Valor e Tipos de Referência.

Usando uma Variável de Tipo que Permite Valor Nulo

Os membros mais importantes de um tipo de valor anulável são as propriedades HasValue e Value dele. Para uma variável de um tipo de valor anulável, HasValue informa se a variável contém um valor definido. Se HasValue for True, você poderá ler o valor de Value. Observe que ambas HasValue e Value são propriedades ReadOnly.

Valores padrão

Quando você declara uma variável com um tipo de valor anulável, a propriedade HasValue dela tem um valor padrão de False. Isso significa que, por padrão, a variável não tem nenhum valor definido, em vez do valor padrão do tipo de valor subjacente. No exemplo a seguir, a variável numberOfChildren inicialmente não tem nenhum valor definido, embora o valor padrão do tipo Integer seja 0.

Dim numberOfChildren? As Integer

Um valor nulo é útil para indicar um valor indefinido ou desconhecido. Se numberOfChildren tivesse sido declarado como Integer, não haveria nenhum valor que pudesse indicar que as informações não estão disponíveis no momento.

Armazenando Valores

Você armazena um valor em uma variável ou propriedade de um tipo de valor anulável da maneira típica. O exemplo a seguir atribui um valor à variável numberOfChildren declarada no exemplo anterior.

numberOfChildren = 2

Se uma variável ou propriedade de um tipo de valor anulável contiver um valor definido, você poderá fazer com que ele seja revertido para o estado inicial de não ter um valor atribuído. Você faz isso definindo a variável ou a propriedade como Nothing, como mostra o exemplo a seguir.

numberOfChildren = Nothing

Observação

Embora você possa atribuir Nothing a uma variável de um tipo de valor anulável, não é possível testá-la para Nothing usando o sinal de igual. Comparação que usa o sinal de igual, someVar = Nothing, sempre é avaliada como Nothing. Você pode testar a propriedade HasValue da variável False ou testar usando o operador o operador Is ou IsNot.

Recuperando Valores

Para recuperar o valor de uma variável de um tipo de valor anulável, primeiro você deve testar a propriedade HasValue dela para confirmar que ela tem um valor. Se você tentar ler o valor quando HasValue estiver False, o Visual Basic lançará uma exceção InvalidOperationException. O exemplo a seguir mostra a maneira recomendada de ler a variável numberOfChildren dos exemplos anteriores.

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

Comparando Tipos que Permitem Valores Nulos

Quando variáveis anuláveis Boolean são usadas em expressões Boolianas, o resultado pode ser True, False ou Nothing. A seguir está a tabela de verdade para And e Or. Como b1 e b2 agora têm três valores possíveis, há nove combinações a serem avaliadas.

b1 b2 b1 E b2 b1 Ou 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 o valor de uma variável ou expressão Booliana é Nothing, ele não é nem true ou false. Considere o exemplo a seguir.

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

Neste exemplo, b1 And b2 avalia como Nothing. Como resultado, a cláusula Else é executada em cada instrução If e a saída é a seguinte:

Expression is not true

Expression is not false

Observação

AndAlso e OrElse, que usam a avaliação de curto-circuito, precisam avaliar os segundos operandos quando o primeiro for avaliado como Nothing.

Propagação

Se um ou ambos os operandos de uma operação aritmética, comparação, deslocamento ou tipo forem um tipo de valor anulável, o resultado da operação também será um tipo de valor anulável. Se ambos os operandos tiverem valores que não são Nothing, a operação será executada nos valores subjacentes dos operandos, como se nenhum deles fosse um tipo de valor anulável. No exemplo a seguir, as variáveis compare1 e sum1 são digitadas implicitamente. Se você descansar o ponteiro do mouse sobre elas, verá que o compilador infere tipos de valor anuláveis para ambas.

' 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 um ou ambos os operandos tiverem um valor de Nothing, o resultado será 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>")}")

Usando Tipos que Permitem Valores Nulos com os Dados

Um banco de dados é um dos locais mais importantes para usar tipos de valor anuláveis. Nem todos os objetos de banco de dados dão suporte atualmente a tipos de valor anuláveis, mas os adaptadores de tabela gerados pelo designer dão. Consulte o Suporte do TableAdapter para tipos que permite valores nulos.

Confira também