2

一个带有 if 内联的简单问题:dim mydate as datetime?


'版本 1(工作!)

If dtReader.IsDBNull(dtReader.GetOrdinal("mydate")) Then
    mydate = Nothing
Else
    mydate = dtReader.GetDateTime(dtReader.GetOrdinal("mydate"))
End If

价值 = 没有


'第 2 版(不工作!)

mydate = If(dtReader.IsDBNull(dtReader.GetOrdinal("mydate")), Nothing, dtReader.GetDateTime(dtReader.GetOrdinal("mydate")))

值 = #12:00:00#


有人能解释一下为什么版本 2 会得到这个值吗?

4

2 回答 2

6

这归结为编译器必须对If. 请记住,Nothing这与 C# 的 null 不同,它更接近于default(T)

如果变量是不可为空的值类型,则将 Nothing 分配给它会将其设置为其声明类型的默认值

现在,当编译器分析时If,它必须决定整个表达式的类型。这是它正在查看的内容:

If(Boolean,<AnyType>,DateTime)

现在,它必须根据第二个和第三个参数的类型来决定表达式的类型是什么,并且它必须选择其中一种存在的类型。所以,很自然地,它选择了DateTime. 而 aNothing转换为 aDateTime与最小值相同。

要改变这一点,让它选择推断类型DateTime?

mydate = If(dtReader.IsDBNull(dtReader.GetOrdinal("mydate")), _
          CType(Nothing,DateTime?), _
          dtReader.GetDateTime(dtReader.GetOrdinal("mydate")))

根据Visual Basic 语言规范,第 11.22 节(条件表达式):

如果提供三个操作数,则所有三个表达式都必须归类为值,并且第一个操作数必须是布尔表达式。如果表达式的结果为真,则第二个表达式将是运算符的结果,否则第三个表达式将是运算符的结果。表达式的结果类型是第二个和第三个表达式类型之间的主要类型。如果没有显性类型,则会发生编译时错误。

(我的重点)。

请注意,没有关于“如果在赋值语句中使用它,您还可以考虑所分配变量的声明类型”的条件文本。

于 2015-12-09T11:14:39.413 回答
2

将选项严格打开!隐式转换正在进行中。

有关示例,请参见此答案。

更新: 如果您设置的类型不可为空,则这两个 if 语句完全相同。如果它们可以为空(默认情况下 DateTime 不是),那么这两个 if 语句会产生不同的结果。例子:

测试1:

代码:

Dim d As DateTime?

d = If(True, Nothing, Now)

结果:

DateTime? dateTime = new DateTime?(DateTime.MinValue);

测试 2:

代码:

Dim d As DateTime?
If True Then
    d = Nothing
Else
    d = Now
End If

结果:

DateTime? dateTime = null;
于 2015-12-09T10:12:26.543 回答