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

Posted

技术标签:

【中文标题】如何在 VB.NET 中将可为空的 DateTime 设置为空?【英文标题】:How do I set a nullable DateTime to null in VB.NET? 【发布时间】:2012-09-17 17:27:40 【问题描述】:

我正在尝试在我的 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。请注意,这两者对于引用类型是等价的。 我个人使用New Date 作为一个幻数,意思是“没有日期”。 另外,您的两位代码似乎混淆了fromDatestartDate @SSS startDate 是我将fromDate 传递给的方法中的参数。 【参考方案1】:

用 VB.NET 和 EF 6.X 保存 null 是:

Dim nullableData As New Nullable(Of Date)

【讨论】:

我认为这是一个有趣的观点,但不确定它是否完全回答了原始问题;)。我在 VB.NET 中将可空日期设置为空,我使用的是nullableData = New Date?【参考方案2】:

除了@Damien_The_Unbeliever 的好答案,使用New DateTime? 也可以:

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

您可能会发现它看起来有点反直觉,为什么CType(Nothing, DateTime?) 更可取。

【讨论】:

【参考方案3】:
        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

【讨论】:

【参考方案4】:

问题在于它首先检查了这个赋值的右侧,并确定它的类型是DateTime(不是?)。然后执行任务。

这将起作用:

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

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

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

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

【讨论】:

正如您在评论中所说的那样,“这两者对于引用类型是等价的”,并且 Nullable(Of DateTime) 是一个引用类型,但它看起来像演员表的作品,谢谢。 Nullable(Of DateTime) 是一个引用类型。但是,在转换Nothing 的时间点,在右侧,我们有这样的类型信息:If(Boolean,DateTime,<Nothing>)。由于If 的返回类型必须匹配其中一个表达式的类型,所以它选择了DateTime。它然后Nothing转换为DateTime(创建一个默认的DateTime),并且只有之后它才会考虑分配。【参考方案5】:

使用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

【讨论】:

您认为分配给Date(或DateTime)变量的New DateNothing 之间有什么区别? (提示 - 没有) 更多输入:Dim fromDate As Date = Nothing Dim fromDate As Date 的输入更少,并且具有相同的可观察效果。 确实如此。但是,fromDate = New Date 是有效的比较,而 fromDate Is Nothing 不是。因此,为了保持一致性,我鼓励一致使用New Date。我还建议将变量显式设置为 NothingNew Date0"" 以指示未初始化的值将用作幻数(并在将它们作为参数传递时避免编译器警告) .我猜这是一种风格偏好——正如你所指出的,在 IL 级别没有区别。 fromDate = Nothing 是一个有效的比较,并且少了一个字符:-)

以上是关于如何在 VB.NET 中将可为空的 DateTime 设置为空?的主要内容,如果未能解决你的问题,请参考以下文章

在 Typescript 中将可为空的对象值转换为字符串

如何将字符串解析为可为空的 int

为啥我不能将 DBNull.Value 插入到 sql server 2005 中的可为空的图像字段中?

如果它为空或为空,如何从序列化中忽略可为空的属性?

如何绑定可为空的十进制值

如何使用 ToString() 格式化可为空的 DateTime?