メンバー アクセス (?.) またはインデックス (?()) 演算を実行する前に、左側のオペランドの値が 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 になる可能性があるオブジェクトに対してアクションを実行する必要があります (次の例の Boolean プロパティ 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 条件演算子はショートサーキットです。 条件付きメンバー アクセスとインデックス操作のチェーン内の 1 つの操作が Nothingを返すと、チェーンの残りの実行は停止します。 次の例では、A、B、またはCがNothingに評価された場合、C(E)は評価されません。
A?.B?.C?(E)
Not someStr?.Contains("some string")またはBoolean?として評価されるその他の値にnothingまたはHasValue=falseの値がある場合、else ブロックが実行されることに注意してください。 この評価は、null/nothing が何も等しくなく、別の null/何も等しくない SQL 評価に従います。
null 条件付きメンバー アクセスのもう 1 つの用途は、はるかに少ないコードでスレッド セーフな方法でデリゲートを呼び出す方法です。 次の例では、 NewsBroadcaster と NewsReceiverの 2 つの型を定義します。 ニュース アイテムは、 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...")
コンパイラが 1 回だけ SendNews 評価するコードを生成し、結果を一時変数に保持するため、新しい方法はスレッド セーフです。 null 条件付きデリゲート呼び出し構文SendNews?(String)がないため、Invoke メソッドを明示的に呼び出す必要があります。
こちらも参照ください
.NET