Freigeben über


?. und? () nullbedingte Operatoren (Visual Basic)

Testet den Wert des linken Operanden auf NULL (Nothing) vor dem Ausführen eines Memberzugriffsvorgangs (?.) oder eines Indexvorgangs?(); gibt zurück Nothing , wenn der linke Operand ausgewertet wird Nothing. Beachten Sie, dass in Ausdrücken, die Werttypen ordinär zurückgeben, der Null-bedingte Operator einen Nullable<T>.

Diese Operatoren helfen Ihnen, weniger Code zur Behandlung von NULL-Prüfungen zu schreiben, insbesondere beim Absteigen in Datenstrukturen. Beispiel:

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

Im Vergleich dazu lautet der alternative Code für den ersten dieser Ausdrücke ohne nullbedingter Operator:

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

Manchmal müssen Sie eine Aktion für ein Objekt ausführen, das null sein kann, basierend auf dem Wert eines booleschen Elements für dieses Objekt (wie die boolesche Eigenschaft IsAllowedFreeShipping im folgenden Beispiel):

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

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

Sie können den Code kürzen und die manuelle Überprüfung auf NULL vermeiden, indem Sie den operator null-bedingt wie folgt verwenden:You can shorten your code and avoid manually checking for null by using the null-conditional operator as follows:

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

If customer?.IsAllowedFreeShipping Then ApplyFreeShippingToOrders(customer)

Die NULL-bedingten Operatoren sind Kurzschlussoperatoren. Wenn ein Vorgang in einer Kette mit bedingtem Memberzugriff und Indexvorgängen zurückgegeben Nothingwird, wird der Rest der Ausführung der Kette beendet. Im folgenden Beispiel wird nicht ausgewertet, C(E) wenn A, Boder C ausgewertet wird.Nothing

A?.B?.C?(E)

Beachten Sie, dass der Block ausgeführt wird, wenn Not someStr?.Contains("some string") oder ein anderer Wert, der ausgewertet Boolean? wird, den Wert nothing oder HasValue=falseden else Wert aufweist. Die Auswertung folgt der SQL-Auswertung, bei der null/nichts nichts gleicht, nicht einmal ein anderer Null/nichts.

Eine weitere Verwendung für den Zugriff auf Null-bedingte Member besteht darin, Stellvertretungen mit viel weniger Code auf threadsichere Weise aufzurufen. Im folgenden Beispiel werden zwei Typen definiert: a NewsBroadcaster und a NewsReceiver. Nachrichtenelemente werden vom NewsBroadcaster.SendNews Delegaten an den Empfänger gesendet.

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

Wenn in der SendNews Aufrufliste keine Elemente vorhanden sind, löst der SendNews Delegat eine NullReferenceException. Vor null-bedingten Operatoren sorgten Code wie die folgenden dafür, dass die Aufrufliste der Stellvertretung nicht Nothinglautete:

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

Die neue Methode ist viel einfacher:

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

Die neue Methode ist threadsicher, da der Compiler Code generiert, um nur einmal auszuwerten SendNews , wobei das Ergebnis in einer temporären Variablen beibehalten wird. Sie müssen die Invoke Methode explizit aufrufen, da keine Syntax SendNews?(String)für bedingte Stellvertretungen vorhanden ist.

Siehe auch