?. 和 ?() null 條件運算子 (Visual Basic)
在執行成員存取 (?.
) 或索引 (?()
) 作業之前,測試左運算元的值是否為 null (Nothing
);如果左運算元評估為 Nothing
,則傳回 Nothing
。 請注意,在通常傳回實值型別的運算式中,null 條件運算子會傳回 Nullable<T>。
這些運算子可協助您撰寫較少的程式碼來處理 null 檢查,特別是遞減至資料結構時。 例如:
' 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()
為了進行比較,這些運算式中第一個沒有 null 條件運算子的替代程式碼為:
Dim length As Integer?
If customers IsNot Nothing Then
length = customers.Length
Else
length = Nothing
End If
有時您需要根據該物件上布林成員的值,對可能為 null 的物件採取動作 (如下列範例中的布林屬性 IsAllowedFreeShipping
):
Dim customer = FindCustomerByID(123) 'customer will be Nothing if not found.
If customer IsNot Nothing AndAlso customer.IsAllowedFreeShipping Then
ApplyFreeShippingToOrders(customer)
End If
您可以縮短程式碼,避免使用 null 條件運算子手動檢查 null,如下所示:
Dim customer = FindCustomerByID(123) 'customer will be Nothing if not found.
If customer?.IsAllowedFreeShipping Then ApplyFreeShippingToOrders(customer)
Null 條件運算子會執行最少運算。 如果條件成員存取和索引作業鏈結中的一個作業傳回 Nothing
,則鏈結的其餘部分會停止執行。 在下列範例中,如果 A
、B
或 C
評估為 Nothing
,則不會評估為 C(E)
。
A?.B?.C?(E)
請注意,如果 Not someStr?.Contains("some string")
或評估為 Boolean?
的任何其他值具有 nothing
或 HasValue=false
的值,則會執行 else
區塊。 評估會遵循 SQL 評估,其中 null/nothing 不等於任何項目,甚至不等於另一個 null/nothing。
null 條件成員存取的另一個用法是,使用更少的程式碼以安全執行緒方式叫用委派。 下列範例會定義兩種型別:NewsBroadcaster
和 NewsReceiver
。 新聞項目會由 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
如果 SendNews
叫用清單中沒有元素,SendNews
委派會擲回 NullReferenceException。 在 null 條件運算子之前,類似下列的程式碼確保了委派叫用清單不是 Nothing
:
SendNews = SendNews.Combine({SendNews, client})
If SendNews IsNot Nothing Then
SendNews("Just in...")
End If
新方法則更簡單:
SendNews = SendNews.Combine({SendNews, client})
SendNews?.Invoke("Just in...")
新的方法可以保障執行緒安全,因為編譯器產生的程式碼只會評估 SendNews
一次,並將結果保留在暫存變數中。 由於沒有 Null 條件式委派引動過程語法 SendNews?(String)
,因此您必須明確呼叫 Invoke
方法。