Dela via


?. Och? () null-villkorsstyrda operatorer (Visual Basic)

Testar värdet för den vänstra operanden för null (Nothing) innan en medlemsåtkomståtgärd (?.) eller index (?()) utförs. Returnerar Nothing om den vänstra operanden utvärderas till Nothing. Observera att i uttryck som normalt returnerar värdetyper returnerar den null-villkorsstyrda operatorn en Nullable<T>.

De här operatorerna hjälper dig att skriva mindre kod för att hantera null-kontroller, särskilt när du går ned i datastrukturer. Till exempel:

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

Som jämförelse är den alternativa koden för det första av dessa uttryck utan en null-villkorsoperator:

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

Ibland måste du vidta en åtgärd för ett objekt som kan vara null, baserat på värdet för en boolesk medlem i objektet (som den booleska egenskapen IsAllowedFreeShipping i följande exempel):

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

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

Du kan förkorta koden och undvika att manuellt söka efter null med hjälp av den null-villkorsstyrda operatorn på följande sätt:

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

If customer?.IsAllowedFreeShipping Then ApplyFreeShippingToOrders(customer)

De null-villkorsstyrda operatorerna kortsluter. Om en åtgärd i en kedja av villkorlig medlemsåtkomst och indexåtgärder returnerar Nothingstoppas resten av kedjans körning. I följande exempel C(E) utvärderas inte om A, Beller C utvärderas till Nothing.

A?.B?.C?(E)

Observera att om Not someStr?.Contains("some string") eller något annat värde som utvärderas som Boolean? har värdet nothing för eller HasValue=false, else körs blocket. Utvärderingen följer SQL-utvärderingen där null/ingenting inte är lika med något, inte ens en annan null/ingenting.

En annan användning för null-villkorlig medlemsåtkomst är att anropa ombud på ett trådsäkert sätt med mycket mindre kod. I följande exempel definieras två typer, en NewsBroadcaster och en NewsReceiver. Nyhetsobjekt skickas till mottagaren av ombudet NewsBroadcaster.SendNews .

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

Om det inte finns några element i SendNews anropslistan genererar ombudet SendNews en NullReferenceException. Innan null-villkorsoperatorer såg kod som följande till att listan över delegerade anrop inte Nothingvar :

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

Det nya sättet är mycket enklare:

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

Det nya sättet är trådsäkert eftersom kompilatorn genererar kod för att endast utvärdera SendNews en gång, vilket behåller resultatet i en tillfällig variabel. Du måste uttryckligen Invoke anropa metoden eftersom det inte finns någon null-villkorlig delegatanropssyntax SendNews?(String).

Se även