?. 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
, B
ou 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 Nothing
fosse:
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.