如何在VB.NET中将可空的DateTime设置为null?

21

我正在尝试在我的UI上设置一个日期范围过滤器,其中包括复选框来指示是否应使用DateTimePicker的值。

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

fromDate设置为Nothing并不会导致它被设置为Nothing,而是会被设置为“12:00:00 AM”,因此下面的If语句会错误地执行过滤,因为startDate不是Nothing

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

如何确保startDate获得Nothing的值?


在VB中,“Nothing”更接近于C#中的“default(T)”,而不是“null”。请注意,对于引用类型,这两者是等效的。 - Damien_The_Unbeliever
我个人使用 New Date 作为魔法数字表示“无日期”。 - SSS
此外,你的两段代码似乎混淆了“fromDate”和“startDate”。 - SSS
@SSS startDate 是一个方法中的参数,我将 fromDate 传递给它。 - ProfK
5个回答

30
问题在于它先检查了这个赋值语句的右侧,然后决定它是 DateTime 类型(没有 ?)。然后再执行赋值操作。
以下代码可以正常工作:
Dim fromDate As DateTime? = If(fromDatePicker.Checked, _
                               fromDatePicker.Value, _
                               CType(Nothing, DateTime?))

因为它强制右侧的类型为 DateTime?

正如我在评论中所说,Nothing 更类似于 C# 的 default(T) 而不是 null

Nothing 代表数据类型的默认值。默认值取决于变量是值类型还是引用类型。


正如您在评论中所说,“对于引用类型,两者是等效的”,而Nullable(Of DateTime)是一个引用类型,但看起来强制转换技巧确实可行,谢谢。 - ProfK
1
Nullable(Of DateTime) 是一个引用类型。然而,在将 Nothing 转换时,右侧有这个类型信息:If(Boolean,DateTime,<Nothing>)。由于 If 的返回类型必须与其表达式之一的类型匹配,它选择了 DateTime。然后它将 Nothing 转换为 DateTime(创建一个默认的 DateTime),只有在这一点之后才考虑赋值。 - Damien_The_Unbeliever

4
使用 VB.NET 和 EF 6.X 保存 null 值的方法如下: Dim nullableData As New Nullable(Of Date)

我认为这是一个有趣的观点,虽然不确定它是否确切地回答了原始问题;)。在VB.NET中将可空日期设置为null时,我使用nullableData = New Date? - Ian Grainger

2
除了 @Damien_The_Unbeliever 的出色答案外,使用 New DateTime? 也可以起作用:
Dim fromDate As DateTime? = If(fromDatePicker.Checked, _
                               fromDatePicker.Value, _
                               New DateTime?)

你可能觉得这看起来有点违反直觉,为什么CType(Nothing, DateTime?)可能更可取。

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

0

New Date用作魔数:

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

你认为将 New DateNothing 分配给一个 Date(或 DateTime)变量之间有什么区别吗?(提示-其实没有区别) - Damien_The_Unbeliever
更多的输入:Dim fromDate As Date = Nothing - SSS
Dim fromDate As Date 这样的写法更省事,而且具有相同的可观察效果。 - Damien_The_Unbeliever
足够正确。但是,fromDate = New Date 是一个有效的比较,而 fromDate Is Nothing 不是。因此,为了保持一致性,我鼓励使用 New Date。我还建议明确地将变量设置为 NothingNew Date0"",以指示未初始化的值将被用作魔术数字(并避免在将它们作为参数传递时出现编译器警告)。我想这只是一种风格偏好 - 如您所述,在 IL 级别上没有任何区别。 - SSS
fromDate = Nothing 是一个有效的比较,而且使用了一个字符少 :-) - Damien_The_Unbeliever
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接