?. 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
, B
nebo 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 NewsBroadcaster
NewsReceiver
. 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 .