?. A? () Podmíněné operátory null (Visual Basic)

Testuje hodnotu levého operandu pro hodnotu null ( ) před provedením operace přístupu ke členu ( ) nebo indexu ( ). Vrátí hodnotu, pokud je levý operand vyhodnocen Nothing ?. jako ?() Nothing Nothing . Všimněte si, že ve výrazech, které obvykle vrací typy hodnot, vrátí podmíněný operátor null Nullable<T> .

Tyto operátory pomáhají psát méně kódu pro zpracování kontrol hodnot null, zejména při sestupném zápisu do datových struktur. Například:

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

Alternativní kód pro první z těchto výrazů bez operátoru podmíněného hodnotou null je pro porovnání následující:

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

Někdy je potřeba provést akci s objektem, který může mít hodnotu null, na základě hodnoty logického člena tohoto objektu (jako je tomu u logické vlastnosti v IsAllowedFreeShipping následujícím příkladu):

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

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

Kód můžete zkrátit a vyhnout se ruční kontrole hodnoty null pomocí podmíněného operátoru null následujícím způsobem:

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

If customer?.IsAllowedFreeShipping Then ApplyFreeShippingToOrders(customer)

Podmíněné operátory s hodnotou null jsou zkrácené. Pokud jedna operace v řetězu podmíněného přístupu členů a indexových operací vrátí , zbytek provádění Nothing řetězu se zastaví. V následujícím příkladu C(E) se nevyhodnotí, jestli A se , nebo B C vyhodnotí jako Nothing .

A?.B?.C?(E)

Dalším použitím pro přístup s podmíněným členem s hodnotou null je vyvolání delegátů způsobem bezpečným pro přístup z více vláken s mnohem menším použitím kódu. Následující příklad definuje dva typy, NewsBroadcaster a NewsReceiver . Zpravodajské položky se odesílají příjemci prostřednictvím NewsBroadcaster.SendNews delegáta.

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

Pokud v seznamu volání nejsou žádné SendNews prvky, delegát SendNews vyvolá NullReferenceException . Před podmíněným operátorem null kód, jako je následující, zajistil, že seznam volání delegáta nebyl Nothing :

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

Nový způsob je mnohem jednodušší:

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

Nový způsob je bezpečný pro přístup z více vláken, protože kompilátor generuje kód pouze pro jedno vyhodnocení, takže výsledek SendNews je v dočasné proměnné. Je třeba explicitně volat metodu , protože neexistuje žádná syntaxe vyvolání podmíněného Invoke delegáta s hodnotou null SendNews?(String) .

Viz také