A simple question with a if inline: dim mydate as datetime?
'Version 1 (WORKS !)
If dtReader.IsDBNull(dtReader.GetOrdinal("mydate")) Then
mydate = Nothing
Else
mydate = dtReader.GetDateTime(dtReader.GetOrdinal("mydate"))
End If
Value = nothing
'Version 2 (DOENSN'T WORK !)
mydate = If(dtReader.IsDBNull(dtReader.GetOrdinal("mydate")), Nothing, dtReader.GetDateTime(dtReader.GetOrdinal("mydate")))
Value = #12:00:00#
Can someone explain me why the version 2 get this value ?
This comes down to the compiler having to do type analysis on the If
. Bear in mind that Nothing
is not the same as C#'s null, it's closer to default(T)
:
If a variable is of a value type that is not nullable, assigning Nothing to it sets it to the default value for its declared type
Now, when the compiler is analysing If
, it's got to decide on the type of the whole expression. Here's what it's looking at:
If(Boolean,<AnyType>,DateTime)
Now, it has to decide what the type of the expression is, based on the types of the second and third parameters, and it has to pick one of the types so present. So, quite naturally, it picks DateTime
. And a Nothing
converted to a DateTime
is the same as the min value.
To change this, give it the choice to deduce the type as DateTime?
instead:
mydate = If(dtReader.IsDBNull(dtReader.GetOrdinal("mydate")), _
CType(Nothing,DateTime?), _
dtReader.GetDateTime(dtReader.GetOrdinal("mydate")))
Per the Visual Basic Language Specification, section 11.22 (Conditional Expressions):
If three operands are provided, all three expressions must be classified as values, and the first operand must be a Boolean expression. If the result is of the expression is true, then the second expression will be the result of the operator, otherwise the third expression will be the result of the operator. The result type of the expression is the dominant type between the types of the second and third expression. If there is no dominant type, then a compile-time error occurs.
(My emphasis).
And note that there's no conditional text about "if this is being used in an assignment statement, you may also take into account the declared type of the variable being assigned".