Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VB.NET If (ternary) bug

Tags:

vb.net

I found a simple bug in VB.NET that can be easily reproduced:

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? = "" 

Question: Is this a bug? Or is there something wrong with me or my PC? If this is a bug, is there a bug report of this (I cant seem to find it)?

Lessons learned:

  1. this is not a bug
  2. nullable date accepts object nothing
  3. nullable date rejects string nothing

pDate = Nothing ' ok. nullable date accepts object nothing
pString = Nothing
pDate = pString ' error. nullable date rejects string nothing
like image 755
Arvin Avatar asked Feb 23 '23 04:02

Arvin


2 Answers

The bug is in your first use of If(), not the second. Contrary to your comment, the result there is not "expected". That call should fail, because "" cannot convert to a date and the ternary operator is typesafe at all levels whether or not the expression is used.

I suspect it succeeds because of a compiler optimization: since everything is all literals, the condition is optimized away. It's harder to make the optimization the second time, because the pString variable might be changed by another thread the compiler doesn't know about yet.

Someone who's handier with IL can probably confirm this.

The real surprise for me is that this is not caught until runtime. I would expect the compiler to notice the type mismatch and complain at that level, rather than waiting until execution. Your VB Option settings may have something to do with that.

like image 109
Joel Coehoorn Avatar answered Mar 06 '23 07:03

Joel Coehoorn


This is pretty interesting. The example above is pretty clear that there is something odd going on. That said, Stack Overflow isn't really a good place to "report" bugs. If you think you have really found a bug you can post your findings to Microsoft connect.

I did a search on connect and there are quite a few quirks with both the VB.NET and C# ternary operator, especially when Nullable value types are involved. This just may be another one of them?

For what it's worth, you can even simplify the case to look like:

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

It is worth noting that every situation that appears to be broken (all cases expect usage of "") does work when the line looks like: pDate = If(False, String.Empty, CType(Nothing, Date?))

Also, Option Strict [On|Off] plays a very big role in this. When Option Strict On is set, then all of these are compile errors. This behavior can only be seen when Option Strict Off. I've put together an example of all the situations here.

In the end, I don't think this is really a bug, but simply one of the pitfalls of using Option Strict Off. It does seem odd (illogical), but then again so does having Option Strict Off. ;)

like image 38
ckittel Avatar answered Mar 06 '23 07:03

ckittel