为什么不能检查“ DateTime”是否为“ Nothing”?


81

在VB.NET中,是否可以将DateTime变量设置为“未设置”?为什么可以将a设置DateTimeNothing,但不能检查是否为a 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.

1
除了下面的John Gant的答案,您还可以检查datetime变量是否为Nothing(请注意,用=代替“ is”)。
DCNYAM

谢谢,使用Dim boolNotSet As Boolean = d =似乎没有什么是最简单的解决方案。与Nullable演员有趣的是,之前从未见过
Muleskinner,

@Chris-我认为他正在使用VB
Karthik Ratnam,

@Karthik Ratnam,是的,但确实是一样的,@ Marc Gravell的回答使所有观点都明白了。
克里斯·哈斯

1
@NYSystemsAnalyst:根据Nothing(Visual Basic),使用= Nothing<> Nothing不好的做法:“在检查引用(或可为空的值类型)变量是否为null时,请不要使用= Nothing<> Nothing。请始终使用Is NothingIsNot Nothing。”
DavidRR 2012年

Answers:


140

这是与IMO VB.Net混淆的最大原因之一。

NothingVB.Net中的等效default(T)于C#:给定类型的默认值。

  • 对于值类型,这基本上等于“零”:0for IntegerFalsefor BooleanDateTime.MinValuefor 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的博客上找到更全面的解释


1
感谢您的解释。有趣的是,isNothing(d)不起作用,但d =没什么!
phn

12

DateTime是一个值类型,这就是为什么它不能为null的原因。您可以检查它是否等于DateTime.MinValue,也可以Nullable(Of DateTime)改用。

VB有时会“有帮助地”使您认为它正在做某些事情,而不是在做。当它允许您将“日期”设置为“无”时,实际上是将其设置为其他值,例如MinValue。

有关值类型与引用类型的广泛讨论,请参见此问题


4

DateTime是一个值类型,这意味着它始终具有某些值。

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

如果您希望DateTime可以采用Nothing值,请使用Nullable DateTime。


4

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

(有关更多信息,请参见Nullable值类型(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]

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

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

1

在任何编程语言中,使用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

末级

'在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

然后,您可以选择可覆盖对象以使其满足您的需要。大量的工作-但如果您确实需要它,可以做到。


1

您还可以使用下面的方法进行简单检查:

If startDate <> Nothing Then
your logic
End If

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


1

您可以像下面这样检查:

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

0

解决此问题的一种方法是改为使用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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.