VB.net中的If()函数之谜

时间:2012-05-22 09:58:39

标签: vb.net if-statement

我有这段代码:

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(整数)

在Quickwatch中,条件将correclty评估为False,但在运行时,If()函数的计算结果为True部分。

3 个答案:

答案 0 :(得分:7)

  

当srcCell.CELL_VALUE_FLOAT为Nothing时,它神秘地评估为True部分!

不,它没有。它只是将错误部分(Nothing)评估为0,从而将CELL_VALUE_INT设置为0。


让我详细说明:表达式

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

使用i填充0。 (测试一下,如果你不相信我的话。)

为什么会这样? VB.NET中的Nothing与C#中的null不同。如果与值类型一起使用,Nothing表示“该类型的默认值”。 If推断Integer(不是Integer?)作为1Nothing的常见类型,因此将Nothing评估为{{1} }}

您可以按照以下方式解决此问题:

default(Integer) = 0

,在你的例子中,意思是

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

现在应该产生正确的值。


由于这是非常令人惊讶的行为,我在前一段时间提交了Microsoft Connect suggestion来添加编译器警告。

答案 1 :(得分:3)

VB.NET中的

Nothing与C#中的null不完全相等 它更像是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)

答案 2 :(得分:0)

假设您的值为Single(浮动):

Single的默认值为0而非Nothing

如果要检查空值,可以使用Nullable(Of T)

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))