为什么我不能检查“日期时间”是否为“无”?

在 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.
113232 次浏览

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

VB 有时候“很有帮助”,让你觉得它在做一些它没有做的事情。当它允许您将 Date 设置为 Nothing 时,它实际上是将其设置为其他值,也许是 MinValue。

有关值类型与引用类型的详细讨论,请参阅 这个问题

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

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

如果需要可以采用 Nothing 值的 DateTime,请使用 Nullable DateTime。

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

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

  • 对于值类型,这实际上等同于‘ zero’: 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

更全面的解释可以在 安东尼 · D · 格林的博客上找到

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

您可以创建一个包含值类型的单独类。从这样的类创建的对象将是引用类型,可以赋予 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

最后一节课

主要内容:

        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

然后你可以选择重写,让它做你需要的。很多工作,但如果你真的需要,你可以做到。

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

(详情请参阅 可为空的值类型(VisualBasic)。)

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

另外,关于如何检查变量是否为 无效(来自 没有(VisualBasic)) :

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

解决这个问题的一种方法是使用 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

你也可以使用下面的简单方法来检查:

If startDate <> Nothing Then
your logic
End If

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

你可以像下面这样检查:

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