Why can't I check if a 'DateTime' is &

2019-01-16 09:35发布

In VB.NET, is there a way to set a DateTime variable to "not set"? And why is it possible to set a DateTime to Nothing, but not possible to check if it is Nothing? For example:

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

The second statement throws this error:

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

8条回答
姐就是有狂的资本
2楼-- · 2019-01-16 10:04

This is one of the biggest sources of confusion with VB.Net, IMO.

Nothing in VB.Net is the equivalent of default(T) in C#: the default value for the given type.

  • For value types, this is essentially the equivalent of 'zero': 0 for Integer, False for Boolean, DateTime.MinValue for DateTime, ...
  • For reference types, it is the null value (a reference that refers to, well, nothing).

The statement d Is Nothing is therefore equivalent to d Is DateTime.MinValue, which obviously does not compile.

Solutions: as others have said

  • Either use DateTime? (i.e. Nullable(Of DateTime)). This is my preferred solution.
  • Or use d = DateTime.MinValue or equivalently d = Nothing

In the context of the original code, you could use:

Dim d As DateTime? = Nothing
Dim boolNotSet As Boolean = d.HasValue
查看更多
神经病院院长
3楼-- · 2019-01-16 10:11

DateTime is a value type, which means it always has some value.

It's like an integer - it can be 0, or 1, or less than zero, but it can never be "nothing".

If you want a DateTime that can take the value Nothing, use a Nullable DateTime.

查看更多
家丑人穷心不美
4楼-- · 2019-01-16 10:11

In any programming language, be careful when using Nulls. The example above shows another issue. If you use a type of Nullable, that means that the variables instantiated from that type can hold the value System.DBNull.Value; not that it has changed the interpretation of setting the value to default using "= Nothing" or that the Object of the value can now support a null reference. Just a warning... happy coding!

You could create a separate class containing a value type. An object created from such a class would be a reference type, which could be assigned Nothing. An example:

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

End Class

'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

Then you could pick and choose overridables to make it do what you need. Lot of work - but if you really need it, you can do it.

查看更多
ら.Afraid
5楼-- · 2019-01-16 10:21

A way around this would be to use Object datatype instead:

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

Then you can set the date to nothing like so:

MyDate = Nothing
Dim theDate As Date = MyDate
If theDate = Nothing Then
    'date is nothing
End If
查看更多
戒情不戒烟
6楼-- · 2019-01-16 10:22

You can also use below just simple to check:

If startDate <> Nothing Then
your logic
End If

It will check that the startDate variable of DateTime datatype is null or not.

查看更多
叛逆
7楼-- · 2019-01-16 10:24

DateTime is a value type, which is why it can't be null. You can check for it to be equal to DateTime.MinValue, or you can use Nullable(Of DateTime) instead.

VB sometimes "helpfully" makes you think it's doing something it's not. When it lets you set a Date to Nothing, it's really setting it to some other value, maybe MinValue.

See this question for an extensive discussion of value types vs. reference types.

查看更多
登录 后发表回答