【问题标题】:Why can't I check if a 'DateTime' is 'Nothing'?为什么我不能检查“日期时间”是否为“无”?
【发布时间】:2019-02-21 04:10:27
【问题描述】:

在 VB.NET 中,有没有办法将 DateTime 变量设置为“未设置”?为什么可以将DateTime 设置为Nothing,但不能 可以检查它是否为Nothing?例如:

Dim d As DateTime = Nothing
Dim boolNotSet As Boolean = d Is Nothing 

第二条语句抛出这个错误:

'Is' operator does not accept operands of type 'Date'. Operands must be reference or
nullable types.

【问题讨论】:

  • 除了下面 John Gant 的回答,您还可以检查 datetime 变量是否 = Nothing(注意 = 而不是“is”)。
  • 谢谢,使用 Dim boolNotSet As Boolean = d = 目前似乎没有最简单的解决方案。以前从未见过的 Nullable 强制转换很有趣
  • @Chris - 我认为他正在使用 VB
  • @Karthik Ratnam,是的,他是,但它等同于同一件事,@Marc Gravell 的回答得到了所有要点。
  • @NYSystemsAnalyst:根据Nothing (Visual Basic),使用= Nothing<> Nothing 不是好的做法:“检查引用(或可空值类型)变量是否为null,不要使用= Nothing<> Nothing。始终使用Is NothingIsNot Nothing。"

标签: vb.net datetime null nullable nothing


【解决方案1】:

这是与 VB.Net、IMO 混淆的最大来源之一。

VB.Net 中的Nothing 相当于 C# 中的default(T):给定类型的默认值。

  • 对于值类型,这基本上相当于“零”:0 表示 IntegerFalse 表示 BooleanDateTime.MinValue 表示 DateTime,...
  • 对于引用类型,它是 null 值(一个引用,嗯,什么都没有)。

语句d Is Nothing因此等价于d Is DateTime.MinValue,显然不能编译。

解决方案:正如其他人所说的那样

  • 要么使用DateTime?(即Nullable(Of DateTime))。这是我的首选解决方案。
  • 或使用d = DateTime.MinValue 或等效的d = Nothing

在原始代码的上下文中,您可以使用:

Dim d As DateTime? = Nothing
Dim boolNotSet As Boolean = d.HasValue

更全面的解释可以在Anthony D. Green's blog找到

【讨论】:

  • 感谢您的解释。有趣的是 isNothing(d) 不起作用,但 d = Nothing 起作用!
【解决方案2】:

DateTime 是一个值类型,这就是它不能为空的原因。你可以检查它是否等于DateTime.MinValue,或者你可以使用Nullable(Of DateTime)

VB 有时“有帮助”让您认为它正在做一些它没有做的事情。当它允许您将 Date 设置为 Nothing 时,实际上是在将其设置为其他值,可能是 MinValue。

请参阅 this question,了解有关值类型与引用类型的广泛讨论。

【讨论】:

    【解决方案3】:

    DateTime 是一个值类型,这意味着它总是有一些值。

    它就像一个整数 - 它可以是 0、1 或小于零,但它永远不会是“无”。

    如果您想要一个可以取值为 Nothing 的 DateTime,请使用 Nullable DateTime。

    【讨论】:

      【解决方案4】:

      一些使用可空DateTime 值的示例。

      (请参阅Nullable Value Types (Visual Basic) 了解更多信息。)

      '
      ' An ordinary DateTime declaration. It is *not* nullable. Setting it to
      ' 'Nothing' actually results in a non-null value.
      '
      Dim d1 As DateTime = Nothing
      Console.WriteLine(String.Format("d1 = [{0}]\n", d1))
      ' Output:  d1 = [1/1/0001 12:00:00 AM]
      
      ' Console.WriteLine(String.Format("d1 is Nothing? [{0}]\n", (d1 Is Nothing)))
      '
      '   Compilation error on above expression '(d1 Is Nothing)':
      '
      '      'Is' operator does not accept operands of type 'Date'.
      '       Operands must be reference or nullable types.
      
      '
      ' Three different but equivalent ways to declare a DateTime
      ' nullable:
      '
      Dim d2? As DateTime = Nothing
      Console.WriteLine(String.Format("d2 = [{0}][{1}]\n", d2, (d2 Is Nothing)))
      ' Output:  d2 = [][True]
      
      Dim d3 As DateTime? = Nothing
      Console.WriteLine(String.Format("d3 = [{0}][{1}]\n", d3, (d3 Is Nothing)))
      ' Output:  d3 = [][True]
      
      Dim d4 As Nullable(Of DateTime) = Nothing
      Console.WriteLine(String.Format("d4 = [{0}][{1}]\n", d4, (d4 Is Nothing)))
      ' Output:  d4 = [][True]
      

      另外,关于如何检查变量是否为null(来自Nothing (Visual Basic)):

      检查引用(或可为空值类型)变量是否为 null 时,不要使用= Nothing<> Nothing。始终使用Is NothingIsNot Nothing

      【讨论】:

        【解决方案5】:

        在任何编程语言中,使用 Null 时都要小心。上面的示例显示了另一个问题。如果使用 Nullable 类型,则意味着从该类型实例化的变量可以保存值 System.DBNull.Value;并不是说它改变了使用“= Nothing”将值设置为默认值的解释,或者值的对象现在可以支持空引用。只是一个警告......快乐的编码!

        您可以创建一个包含值类型的单独类。从这样的类创建的对象将是一个引用类型,它可以被赋值为 Nothing。一个例子:

        Public Class DateTimeNullable
        Private _value As DateTime
        
        'properties
        Public Property Value() As DateTime
            Get
                Return _value
            End Get
            Set(ByVal value As DateTime)
                _value = value
            End Set
        End Property
        
        'constructors
        Public Sub New()
            Value = DateTime.MinValue
        End Sub
        
        Public Sub New(ByVal dt As DateTime)
            Value = dt
        End Sub
        
        'overridables
        Public Overrides Function ToString() As String
            Return Value.ToString()
        End Function
        

        结束类

        'in Main():

                Dim dtn As DateTimeNullable = Nothing
            Dim strTest1 As String = "Falied"
            Dim strTest2 As String = "Failed"
            If dtn Is Nothing Then strTest1 = "Succeeded"
        
            dtn = New DateTimeNullable(DateTime.Now)
            If dtn Is Nothing Then strTest2 = "Succeeded"
        
            Console.WriteLine("test1: " & strTest1)
            Console.WriteLine("test2: " & strTest2)
            Console.WriteLine(".ToString() = " & dtn.ToString())
            Console.WriteLine(".Value.ToString() = " & dtn.Value.ToString())
        
            Console.ReadKey()
        
            ' Output:
            'test1:  Succeeded()
            'test2:  Failed()
            '.ToString() = 4/10/2012 11:28:10 AM
            '.Value.ToString() = 4/10/2012 11:28:10 AM
        

        然后,您可以挑选可覆盖项以使其满足您的需求。很多工作 - 但如果你真的需要,你可以做到。

        【讨论】:

          【解决方案6】:

          您也可以使用下面的简单检查:

          If startDate <> Nothing Then
          your logic
          End If
          

          它会检查 DateTime 数据类型的 startDate 变量是否为空。

          【讨论】:

            【解决方案7】:

            你可以像下面这样检查:

            if varDate = "#01/01/0001#" then
                   '  blank date. do something.
            else
                   ' Date is not blank. Do some other thing
            end if
            

            【讨论】:

              【解决方案8】:

              解决这个问题的方法是使用 Object 数据类型:

              Private _myDate As Object
              Private Property MyDate As Date
                  Get
                      If IsNothing(_myDate) Then Return Nothing
                      Return CDate(_myDate)
                  End Get
                  Set(value As Date)
                      If date = Nothing Then
                          _myDate = Nothing
                          Return
                      End If
                      _myDate = value
                   End Set
              End Property
              

              然后您可以将日期设置为这样:

              MyDate = Nothing
              Dim theDate As Date = MyDate
              If theDate = Nothing Then
                  'date is nothing
              End If
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-02-13
                • 1970-01-01
                • 1970-01-01
                • 2023-04-11
                • 1970-01-01
                • 1970-01-01
                • 2015-10-01
                • 1970-01-01
                相关资源
                最近更新 更多