3

以下に示すように、タイプがデフォルト値Nullableであるプロパティがあります。IntegerNothing

Property TestId As Integer? = Nothing

次のコードは、プロパティTestIdをNothingに評価します(必要に応じて)

Dim test As RadTreeNode = rtvDefinitionCreate.FindNodeByValue(DefinitionHeaderEnum.Test)
If test Is Nothing Then
    definition.TestId = Nothing
Else
    definition.TestId = test.Nodes(0).Value
End If

ただし、以下のコードは0と評価されます(がデフォルト値のInteger場合でも、Integer?のデフォルト値Nothing

Dim test As RadTreeNode = rtvDefinitionCreate.FindNodeByValue(DefinitionHeaderEnum.Test)
definition.TestId = If(IsNothing(test), Nothing, test.Nodes(0).Value)

上記のコードの何が問題になっていますか?ヘルプはありますか?

(後でプロパティを呼び出すときのコードでは、プロパティには0があります)

4

1 に答える 1

2

でコードをコンパイルしているためですOption Strict Off

コードを でコンパイルすると、コンパイラは からにOption Strict On変換できないことを示すエラーを表示し、実行時のそのような驚きを回避します。StringInteger?


これは、VB.NET でproperties//を使用する場合の奇妙な点です。ternary operatoroption strict off

次のコードを検討してください。

Class Test
    Property NullableProperty As Integer? = Nothing
    Public NullableField As Integer? = Nothing
End Class

Sub Main()
    ' Setting the Property directly will lest the ternary operator evaluate to zero
    Dim b = New Test() With {.NullableProperty = If(True, Nothing, "123")}
    b.NullableProperty = If(True, Nothing, "123")

    ' Setting the Property with reflection or setting a local variable 
    ' or a public field lets the ternary operator evaluate to Nothing
    Dim localNullable As Integer? = If(True, Nothing, "123")
    Dim implicitLocal = If(True, Nothing, "123")
    b.NullableField = If(True, Nothing, "123")
    b.GetType().GetMethod("set_NullableProperty").Invoke(b, New Object() {If(True, Nothing, "123")})
    b.GetType().GetProperty("NullableProperty").SetValue(b, If(True, Nothing, "123"), Nothing)
End Sub

考慮すべきもう 1 つの違い:

Dim localNullable As Integer? = If(True, Nothing, "123") 

に評価されNothingますが

Dim localNullable As Integer? = If(SomeNonConstantCondition, Nothing, "123") 

に評価されます0


厄介な作業を行う拡張メソッドを作成できます。

<Extension()>
Function TakeAs(Of T, R)(obj As T, selector As Func(Of T, R)) As R
    If obj Is Nothing Then
        Return Nothing
    End If
    Return selector(obj)
End Function

そしてそれを次のように呼び出します

definition.TestId = test.TakeAs(Of Int32?)(Function(o) o.Nodes(0).Value)
于 2012-07-12T06:38:23.000 に答える