Reputation: 33
I have a ternary expression that checks to see if an Object
is DBNull.Value
and returns Nothing
if True
else if False
returns the value converted to the Date
type of that Object
. However, for some strange reason my nullable DateTime
variable that is being set by the ternary expression is mysteriously set to '1/1/0001 12:00:00 AM'
even though Object
is most certainly a DBNull.Value
. Can anyone else reproduce this behavior? If so, why does it happen?
The strange part is that I've changed this expression to regular old if and else blocks and I don't get this behavior at all. So, it has to be something to do with the ternary statement.
Module Module1
Sub Main()
Dim dt As New DataTable
dt.Columns.Add(New DataColumn("DateColumn", GetType(String)))
dt.Rows.Add()
Dim testDate = dt(0).Item(0)
Dim setDate As DateTime? = Nothing
'Doesn't work
setDate = If(testDate Is DBNull.Value, Nothing, CDate(testDate))
'Works
'If testDate Is DBNull.Value Then
' setDate = Nothing
'Else
' setDate = CDate(testDate)
'End If
'Also works
'setDate = If(testDate Is DBNull.Value, Nothing, CType(testDate, DateTime?))
'This works too
'setDate = If(testDate Is DBNull.Value, Nothing, testDate)
'Working
'setDate = IIf(testDate Is DBNull.Value, Nothing, testDate)
If setDate IsNot Nothing Then
Console.WriteLine("Why does setDate = '" & setDate.ToString & "' ?!")
End If
Console.ReadKey()
End Sub
End Module
I would like to use the ternary statement because it is less code.
Upvotes: 2
Views: 144
Reputation: 17845
The reason is that VB infers the return type of the If
operator to be a Date
because that is what CDate returns. The Nothing
keyword can be converted to a non-nullable Date
object because Nothing also means "default" in VB, and the default value of a Date is 1/1/0001 12:00:00 AM
. To fix this you have to make sure at least one of the parameters is explicitely a DateTime?
.
For example, this would work:
setDate = If(testDate Is DBNull.Value, New DateTime?, CDate(testDate))
Upvotes: 2