lizaardman04
lizaardman04

Reputation: 33

Issue With .NET Ternary Operator and Type Conversions

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

Answers (1)

Meta-Knight
Meta-Knight

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

Related Questions