VB.NET如果(三元)bug

时间:2011-08-27 01:17:34

标签: vb.net

我在VB.NET中发现了一个可以轻松复制的简单错误:

Dim pDate As Date?
Dim pString As String = ""

' works fine as expected
pDate = If(False, "", Nothing) 

' expected: pDate will be set to Nothing. 
' BUG: Conversion from string "" to type 'Date' is not valid.
pDate = If(False, pString, Nothing) 

'These both fail with the same error
pDate = pString
Dim pDate2 As Date? = "" 

问题:这是一个错误吗?或者我或我的电脑有问题吗? 如果这是一个错误,是否有错误报告(我似乎无法找到它)?

经验教训:

  1. 这不是错误
  2. 可以为空的日期不接受任何对象
  3. 可以为空的日期拒绝字符串

  4. pDate = Nothing ' ok. nullable date accepts object nothing
    pString = Nothing
    pDate = pString ' error. nullable date rejects string nothing
    

2 个答案:

答案 0 :(得分:5)

这个错误是你第一次使用If()而不是第二次。与您的评论相反,结果并非“预期”。该调用应该失败,因为“”无法转换为日期,并且三元运算符在所有级别都是类型安全的,无论是否使用该表达式。

我怀疑它是因为编译器优化而成功:因为一切都是文字,所以条件被优化掉了。第二次进行优化比较困难,因为pString变量可能被编译器还不知道的另一个线程改变了。

对IL有用的人可能会证实这一点。

对我来说真正的惊喜是,直到运行时才会发现这一点。我希望编译器注意到类型不匹配并在该级别进行抱怨,而不是等到执行。您的VB选项设置可能与此有关。

答案 1 :(得分:3)

这非常有趣。上面的例子很清楚,有些奇怪的事情发生了。也就是说,Stack Overflow并不是一个“报告”错误的好地方。如果您认为自己确实发现了错误,可以将结果发布到Microsoft connect

我在连接上进行了搜索,并且VB.NET和C#三元运算符都存在很多怪癖,特别是涉及Nullable值类型时。这可能只是另一个吗?

对于它的价值,您甚至可以简化案例:

Dim pDate As Date?
pDate = If(False, "", Nothing) ' Works fine
pDate = If(False, String.Empty, Nothing) ' Doesn't work

值得注意的是,当行看起来像"" pDate = If(False, String.Empty, CType(Nothing, Date?)))确实有效 >

此外,Option Strict [On|Off]在这方面起着非常重要的作用。设置Option Strict On时,所有这些都是编译错误。只有在Option Strict Off时才能看到此行为。我把an example of all the situations here放在一起。

最后,我认为这不是一个真正的错误,而只是使用Option Strict Off的一个陷阱。它似乎很奇怪(不合逻辑),但是再次如此Option Strict Off。 ;)