Partilhar via


?. e ? () operadores condicionais nulos (Visual Basic)

Testa o valor do operando esquerdo para null (Nothing) antes de executar uma operação de acesso de membro (?.) ou índice (?()); retorna Nothing se o operando esquerdo for avaliado como Nothing. Observe que em expressões que normalmente retornam tipos de valor, o operador condicional nulo retorna um Nullable<T>arquivo .

Esses operadores ajudam você a escrever menos código para lidar com verificações nulas, especialmente ao descer para estruturas de dados. Por exemplo:

' Nothing if customers is Nothing
Dim length As Integer? = customers?.Length

' Nothing if customers is Nothing
Dim first As Customer = customers?(0)

' Nothing if customers, the first customer, or Orders is Nothing
Dim count As Integer? = customers?(0)?.Orders?.Count()

Para comparação, o código alternativo para a primeira dessas expressões sem um operador condicional nulo é:

Dim length As Integer?
If customers IsNot Nothing Then
   length = customers.Length
Else
    length = Nothing
End If

Às vezes, você precisa executar uma ação em um objeto que pode ser nulo, com base no valor de um membro booleano nesse objeto (como a propriedade IsAllowedFreeShipping Boolean no exemplo a seguir):

Dim customer = FindCustomerByID(123) 'customer will be Nothing if not found.

If customer IsNot Nothing AndAlso customer.IsAllowedFreeShipping Then
  ApplyFreeShippingToOrders(customer)
End If

Você pode encurtar seu código e evitar a verificação manual de null usando o operador null-conditional da seguinte maneira:

Dim customer = FindCustomerByID(123) 'customer will be Nothing if not found.

If customer?.IsAllowedFreeShipping Then ApplyFreeShippingToOrders(customer)

Os operadores condicionais nulos são curto-circuitos. Se uma operação em uma cadeia de acesso de membro condicional e operações de índice retornar Nothing, o restante da execução da cadeia será interrompido. No exemplo a seguir, C(E) não é avaliado se A, Bou C avalia como Nothing.

A?.B?.C?(E)

Observe que se Not someStr?.Contains("some string") ou qualquer outro valor que avalia como Boolean? tem o valor de nothing ou HasValue=false, o else bloco é executado. A avaliação segue a avaliação SQL onde null/nothing não é igual a nada, nem mesmo outro null/nothing.

Outro uso para acesso de membro nulo e condicional é invocar delegados de forma segura para threads com muito menos código. O exemplo a seguir define dois tipos, a NewsBroadcaster e a NewsReceiver. As notícias são enviadas ao destinatário pelo NewsBroadcaster.SendNews delegado.

Public Module NewsBroadcaster
   Dim SendNews As Action(Of String)

   Public Sub Main()
      Dim rec As New NewsReceiver()
      Dim rec2 As New NewsReceiver()
      SendNews?.Invoke("Just in: A newsworthy item...")
   End Sub

   Public Sub Register(client As Action(Of String))
      SendNews = SendNews.Combine({SendNews, client})
   End Sub
End Module

Public Class NewsReceiver
   Public Sub New()
      NewsBroadcaster.Register(AddressOf Me.DisplayNews)
   End Sub

   Public Sub DisplayNews(newsItem As String)
      Console.WriteLine(newsItem)
   End Sub
End Class

Se não houver elementos na SendNews lista de invocação, o SendNews delegado lançará um NullReferenceExceptionarquivo . Antes dos operadores condicionais nulos, um código como o seguinte assegurava que a lista de invocação de delegados não Nothingfosse:

SendNews = SendNews.Combine({SendNews, client})
If SendNews IsNot Nothing Then
   SendNews("Just in...")
End If

A nova forma é muito mais simples:

SendNews = SendNews.Combine({SendNews, client})
SendNews?.Invoke("Just in...")

A nova maneira é thread-safe porque o compilador gera código para avaliar SendNews apenas uma vez, mantendo o resultado em uma variável temporária. Você precisa chamar explicitamente o Invoke método porque não há sintaxe de invocação SendNews?(String)de delegado nulo-condicional.

Consulte também