Sdílet prostřednictvím


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

Testuje hodnotu levého operandu pro hodnotu null (Nothing) před provedením operace přístupu člena (?.) nebo indexu (?()) a vrátí Nothing hodnotu, pokud se operand vlevo vyhodnotí jako Nothing. Všimněte si, že ve výrazech, které obvykle vracejí typy hodnot, vrátí operátor s podmínkou Nullable<T>null hodnotu .

Tyto operátory pomáhají psát méně kódu pro zpracování kontrol null, zejména při sestupném sestupu do datových struktur. Pří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()

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

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

Někdy potřebujete provést akci u objektu, který může mít hodnotu null na základě hodnoty logického člena daného objektu (například boolean vlastnost IsAllowedFreeShipping v 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 zkratové. Pokud jedna operace v řetězci podmíněného přístupu k členům a indexovací operace vrátí Nothing, zastaví se zbytek provádění řetězu. V následujícím příkladu se nevyhodnocuje, C(E) pokud A, Bnebo C se vyhodnotí jako Nothing.

A?.B?.C?(E)

Všimněte si, že pokud Not someStr?.Contains("some string") nebo jakákoli jiná hodnota, která se vyhodnotí jako Boolean? hodnota nothing nebo HasValue=false, else je blok spuštěn. Vyhodnocení se řídí vyhodnocením SQL, kdy hodnota null/nothing se nic nerovná, ani jiná hodnota null/nic.

Další možností použití podmíněného přístupu členů s hodnotou null je vyvolat delegáty způsobem bezpečným pro vlákno s mnohem menším kódem. Následující příklad definuje dva typy, a NewsBroadcasterNewsReceiver. Příspěvky se odesílají příjemci delegátem 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

Pokud v seznamu vyvolání nejsou žádné prvky SendNews , SendNews delegát vyvolá výjimku NullReferenceException. Před podmíněným operátory s hodnotou null kód podobný následujícímu zajistil, že seznam vyvolá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 vygeneruje kód, který vyhodnocuje SendNews pouze jeden čas a výsledek se zachová v dočasné proměnné. Je nutné explicitně volat metodu Invoke , protože neexistuje žádná syntaxe SendNews?(String)volání delegáta s podmínkou null .

Viz také