VB.NET没什么日期时间?的DataReader

时间:2015-12-09 09:53:32

标签: vb.net datetime nullable datareader getvalue

if inline的一个简单问题: dim mydate as datetime?

'版本1(WORKS!)

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

价值=没有

'第2版(DOENSN' T WORK!)

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

价值=#12:00:00#

有人可以解释为什么版本2会获得此值吗?

2 个答案:

答案 0 :(得分:5)

这归结为编译器必须对If进行类型分析。请记住Nothing与C#的null不同,它更接近default(T)

  

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

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

If(Boolean,<AnyType>,DateTime)

现在,它必须根据第二个和第三个参数的类型来决定表达式的类型,并且必须选择其中一个类型。所以,很自然地,它会选择DateTime。转换为Nothing的{​​{1}}与最小值相同。

要更改此设置,请将选项命名为DateTime,而不是<{>}}:

DateTime?

根据Visual Basic Language Specification,第11.22节(条件表达式):

  

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

(我强调)。

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

答案 1 :(得分:2)

开关选项严格开启!隐含的转换正在进行中。

请参阅this答案。

更新:如果您设置的类型不可为空,则这两个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;