5

私はこのコードを持っています:

dstCell.CELL_VALUE_INT = If(srcCell.CELL_VALUE_FLOAT IsNot Nothing,
                            Math.Round(CDbl(srcCell.CELL_VALUE_FLOAT)),
                            Nothing)

srcCell.CELL_VALUE_FLOAT が Nothingの場合、不思議なことに True 部分に評価されます!

面白い部分は、通常の If ステートメントが False 部分に正しく評価されることです。

If (srcCell.CELL_VALUE_FLOAT IsNot Nothing) Then
    dstCell.CELL_VALUE_INT = Math.Round(CDbl(srcCell.CELL_VALUE_FLOAT))
Else
    dstCell.CELL_VALUE_INT = Nothing
End If

何か案は?

ありがとう!

編集: CELL_VALUE_FLOAT は Nullable(Of Double) であり、CELL_VALUE_INT は Nullable(of Integer) です

Quickwatch では、条件は False に正しく評価されますが、If() 関数を実行すると True 部分に評価されます。

4

3 に答える 3

8

srcCell.CELL_VALUE_FLOAT が Nothing の場合、不思議なことに True 部分に評価されます!

いいえ、そうではありません。false の部分 ( Nothing) を として評価するだけなので、 00に設定されます。CELL_VALUE_INT


詳しく説明しましょう: 式

Dim i As Integer? = If(False, 1, Nothing)

で満たさi0ます。(信じられない場合は、テストしてください。)

なぜこれが起こるのですか?VB.NETでは C#Nothingと同じではありません。null値型で使用する場合、Nothing「その型のデフォルト値」を意味します。との共通型として( ではなく) をIf推論し、したがって、 として評価されます。IntegerInteger?1NothingNothingdefault(Integer) = 0

これは次のように修正できます。

Dim i As Integer? = If(False, 1, DirectCast(Nothing, Integer?))

これは、あなたの例では、

dstCell.CELL_VALUE_INT = If(srcCell.CELL_VALUE_FLOAT IsNot Nothing,   
                            Math.Round(CDbl(srcCell.CELL_VALUE_FLOAT)),   
                            DirectCast(Nothing, Integer?))  

これで正しい値が得られるはずです。


これは非常に驚くべき動作であるため、コンパイラの警告を追加するように、少し前にMicrosoft Connect の提案を提出しました。

于 2012-05-22T10:19:44.967 に答える
4

NothingnullVB.NETでは C# と完全に等しいわけではありませんdefault(T)。T が型である場合に似ています。

' VB:
dim x as DateTime = DateTime.MinValue
If x Is Nothing then
    Console.WriteLine("True")
End if

' C#
var x = DateTime.MinValue
if (x == default(DateTime))
    Console.WriteLine("True");

if (x == null) ' throw a compile time error

dim x as Double = nothing ' x will be 0 (default for Double)

両方の戻り値が同じ型であると予想される場合は、インラインでビルドします。だから、あなたが本当にやっていることは次のとおりです。

dstCell.CELL_VALUE_INT = If(srcCell.CELL_VALUE_FLOAT IsNot Nothing,
                            Math.Round(CDbl(srcCell.CELL_VALUE_FLOAT)),
                            Convert.ToDouble(Nothing))

false の部分は内部で double に変換されdstCell.CELL_VALUE_INT、何もないのではなく 0 になるためです。

これを試してください:

dstCell.CELL_VALUE_INT = If(srcCell.CELL_VALUE_FLOAT IsNot Nothing,
                         Ctype(Math.Round(CDbl(srcCell.CELL_VALUE_FLOAT)), Integer?),
                         Nothing)
于 2012-05-22T10:30:18.410 に答える
0

Singleあなたの価値が(フロート)であると仮定すると:

のデフォルト値Singleは0ではありませんNothing

Nullable(Of T)null値をチェックする場合は、を使用できます。

Dim srcCell.CELL_VALUE_FLOAT As Nullable(Of Single)
srcCell_CELL.VALUE_FLOAT = Nothing
Dim dstCell.CELL_VALUE_INT As Nullable(Of Int32) = _
    (If(srcCell.CELL_VALUE_FLOAT.HasValue,
        CInt(Math.Round(CDbl(srcCell.CELL_VALUE_FLOAT))),
        Nothing))
于 2012-05-22T10:07:37.523 に答える