cを計算するための以下の2つの方法に違いはありますか...特にボックス化/ボックス化解除の問題はありますか?
Dim a As Integer? = 10
Dim b As Integer? = Nothing
Dim c As Integer
' Method 1
c = If(a, 0) + If(b, 0)
' Method 2
c = a.GetValueOrDefault(0) + b.GetValueOrDefault(0)
c = If(a, 0) + If(b, 0) ステートメントは次のようにコンパイルされます。
Dim tmpa As Integer
If a.HasValue Then
tmpa = a.GetValueOrDefault()
Else
tmpa = 0
End If
Dim tmpb As Integer
If b.HasValue Then
tmpb = b.GetValueOrDefault()
Else
tmpb = 0
End If
c = tmpa + tmpb
2 番目のスニペットはそのままコンパイルされます。ここは明らかに勝者です。
Reflector によると、コード スニペットの IL は次のように逆コンパイルされます。
Public Shared Sub Main()
Dim a As Integer? = 10
Dim b As Integer? = Nothing
Dim c As Integer = (IIf(a.HasValue, a.GetValueOrDefault, 0) + IIf(b.HasValue, b.GetValueOrDefault, 0))
c = (a.GetValueOrDefault(0) + b.GetValueOrDefault(0))
End Sub
[編集]そして、Reflected関数を見て、(それぞれ)以下を提供しますGetValueOrDefault()
:GetValueOrDefault(T defaultValue)
Public Function GetValueOrDefault() As T
Return Me.value
End Function
と
Public Function GetValueOrDefault(ByVal defaultValue As T) As T
If Not Me.HasValue Then
Return defaultValue
End If
Return Me.value
End Function
どちらの形式を指定しても、事実上まったく同じことが行われます
a.GetValueOrDefault(0)
のわずかに効率的なバージョンですIf(a, 0)
a.GetValueOrDefault()
のわずかに効率的なバージョンですa.GetValueOrDefault(0)
もちろん、これは数値型にのみ当てはまります。