How do I set a nullable DateTime to null in VB.NET?
Asked Answered
K

5

21

I am trying to set up a date range filter on my UI, with checkboxes to say whether a DateTimePicker's value should be used, e.g.

Dim fromDate As DateTime? = If(fromDatePicker.Checked, fromDatePicker.Value, Nothing)

Yet setting fromDate to Nothing doesn't result in it being set to Nothing but to '12:00:00 AM', and the following If statement incorrectly executes the filter because startDate is not Nothing.

If (Not startDate Is Nothing) Then
    list = list.Where(Function(i) i.InvDate.Value >= startDate.Value)
End If

How do I really ensure startDate gets a value of Nothing?

Kielty answered 26/9, 2012 at 6:29 Comment(4)
Nothing in VB is closer to being default(T) in C#, rather than null. Note that the two are equivalent for reference types.Imperishable
I personally use New Date as a magic number that means "No Date".Fourchette
Also, your two bits of code seem to mix up fromDate and startDateFourchette
@Fourchette startDate is a parameter in a method I pass fromDate to.Kielty
I
30

The issue is that it's examining the right-hand side of this assignment first, and deciding that it is of type DateTime (no ?). Then performing the assignment.

This will work:

Dim fromDate As DateTime? = If(fromDatePicker.Checked, _
                               fromDatePicker.Value, _
                               CType(Nothing, DateTime?))

Because it forces the right-hand side's type to be DateTime?.

As I said in my comment, Nothing can be more akin to C#'s default(T) rather than null:

Nothing represents the default value of a data type. The default value depends on whether the variable is of a value type or of a reference type.

Imperishable answered 26/9, 2012 at 6:38 Comment(2)
As you said in your comment as well, "the two are equivalent for reference types", and Nullable(Of DateTime) is a reference type, but it looks like the cast trick works, thanks.Kielty
Nullable(Of DateTime) is a reference type. However, at the point in time when Nothing was being converted, on the right hand side, we have this type information: If(Boolean,DateTime,<Nothing>). Since the return type of If has to match the type of one of its expressions, it picked DateTime. It then converts Nothing to a DateTime (creating a default DateTime), and only after that point does it consider the assignment.Imperishable
G
4

With VB.NET and EF 6.X to save null is:

Dim nullableData As New Nullable(Of Date)

Garamond answered 19/12, 2014 at 13:24 Comment(1)
I think this is an interesting point, though not sure it's exactly answering the original question ;). Where I'm setting a nullable date to null in VB.NET I'm using nullableData = New Date?.Rancell
L
2

In addition to @Damien_The_Unbeliever's fine answer, using New DateTime? also works:

Dim fromDate As DateTime? = If(fromDatePicker.Checked, _
                               fromDatePicker.Value, _
                               New DateTime?)

You might find that it looks a bit counter intuitive, why perhaps the CType(Nothing, DateTime?) is preferable.

Live answered 30/1, 2014 at 23:0 Comment(0)
F
0

Use New Date as a magic number:

Dim fromDate As New Date
If fromDatePicker.Checked Then
  fromDate = fromDatePicker.Value
End If
If fromDate <> New Date Then
  list = list.Where(Function(i) i.InvDate.Value >= fromDate.Value)
End If
Fourchette answered 26/9, 2012 at 6:42 Comment(7)
What do you think the difference is between New Date and Nothing being assigned to a Date (or DateTime) variable? (hint - there isn't one)Imperishable
More typing: Dim fromDate As Date = NothingFourchette
Dim fromDate As Date is even less typing and has the same observable effects.Imperishable
True enough. However, fromDate = New Date is a valid comparison, while fromDate Is Nothing is not. So for consistency I would encourage consistent use of New Date. I also recommend explicitly setting variables to Nothing or New Date or 0 or "" to indicate that the uninitialised value is going to be used as a magic number (and to avoid compiler warnings when you hand them as parameters). It's a style preference I guess - makes no difference at the IL level, as you note.Fourchette
fromDate = Nothing is a valid comparison, and uses one less character :-)Imperishable
@Fourchette Surely we should be moving away from using legacy types/aliases such as Date?Kielty
I guess that's a style choice too. As I said before, YMMV.Fourchette
C
0
        squery = "insert into tblTest values('" & Me.txtCode.Text & "', @Date)"
        Dim cmd = New SqlCommand(squery, con)

        cmd.Parameters.Add("@Date", SqlDbType.DateTime)
        If txtRequireDate.Text = "" Then
            cmd.Parameters("@Date").Value = DBNull.Value
        Else
            cmd.Parameters("@Date").Value = txtRequireDate.Text
        End If
Cutworm answered 16/12, 2013 at 5:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.