Delen via


?. En? () null-conditional operators (Visual Basic)

Test de waarde van de linkeroperand voor null (Nothing) voordat een lidtoegang (?.) of indexbewerking wordt?() uitgevoerd; retourneert Nothing als de linkeroperand resulteert in Nothing. In expressies die gewoonlijk waardetypen retourneren, retourneert de operator null-voorwaardelijke waarden een Nullable<T>.

Deze operators helpen u minder code te schrijven voor het afhandelen van null-controles, met name wanneer u aflopend in gegevensstructuren. Voorbeeld:

' 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()

Ter vergelijking is de alternatieve code voor de eerste van deze expressies zonder een null-voorwaardelijke operator:

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

Soms moet u een actie uitvoeren op een object dat null kan zijn, op basis van de waarde van een Booleaanse lid op dat object (zoals de booleaanse eigenschap IsAllowedFreeShipping in het volgende voorbeeld):

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

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

U kunt uw code verkorten en handmatig controleren op null voorkomen door de operator null-voorwaardelijke invoer als volgt te gebruiken:

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

If customer?.IsAllowedFreeShipping Then ApplyFreeShippingToOrders(customer)

De null-voorwaardelijke operators zijn kortsluiting. Als één bewerking in een keten van voorwaardelijke lidtoegang en indexbewerkingen Nothingwordt geretourneerd, stopt de rest van de uitvoering van de keten. In het volgende voorbeeld C(E) wordt niet geëvalueerd of A, Bof C wordt geëvalueerd .Nothing

A?.B?.C?(E)

Houd er rekening mee dat als Not someStr?.Contains("some string") of een andere waarde die de Boolean? waarde heeft van nothing of HasValue=false, het else blok wordt uitgevoerd. De evaluatie volgt de SQL-evaluatie waarbij null/niets niets gelijk is aan niets, zelfs niet een andere null/niets.

Een ander gebruik voor toegang tot null-voorwaardelijke leden is het aanroepen van gemachtigden op een thread-veilige manier met veel minder code. In het volgende voorbeeld worden twee typen, a NewsBroadcaster en a NewsReceivergedefinieerd. Nieuwsitems worden door de gemachtigde naar de NewsBroadcaster.SendNews ontvanger verzonden.

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

Als er geen elementen in de SendNews aanroeplijst staan, genereert de SendNews gedelegeerde een NullReferenceException. Voordat er null-voorwaardelijke operators waren, zorgde code zoals hieronder ervoor dat de lijst met gemachtigde aanroepen niet Nothingwas:

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

De nieuwe manier is veel eenvoudiger:

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

De nieuwe manier is thread-safe omdat de compiler code genereert om slechts één keer te evalueren SendNews , waardoor het resultaat in een tijdelijke variabele blijft. U moet de Invoke methode expliciet aanroepen omdat er geen aanroepsyntaxis SendNews?(String)voor null-voorwaardelijke gemachtigden is.

Zie ook