Почему я не могу проверить, является ли DateTime 'Nothing'? - PullRequest
73 голосов
/ 03 мая 2011

В 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.

Ответы [ 8 ]

130 голосов
/ 03 мая 2011

Это один из самых больших источников путаницы с VB.Net, IMO.

Nothing в VB.Net является эквивалентом default(T) в C #: значение по умолчанию для данного типа.

  • Для типов значений это, по сути, эквивалент «нуля»: 0 для Integer, False для Boolean, DateTime.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

Более подробное объяснение можно найти в блоге Энтони Д. Грина

10 голосов
/ 03 мая 2011

DateTime - это тип значения, поэтому он не может быть нулевым. Вы можете проверить, чтобы оно было равно DateTime.MinValue, или вместо него можно использовать Nullable(Of DateTime).

VB иногда "услужливо" заставляет вас думать, что он делает что-то, чего нет. Когда он позволяет установить для параметра «Дата» значение «ничего», он действительно устанавливает для него другое значение, например MinValue.

См. этот вопрос для подробного обсуждения типов значений и ссылочных типов.

3 голосов
/ 12 сентября 2012

Некоторые примеры работы со значениями 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]

Кроме того, о том, как проверить, является ли переменная пустым (из Ничего (Visual Basic) ):

При проверке, является ли переменная-ссылка (или тип значения, допускающее значение NULL) null , не используйте = Nothing или <> Nothing. Всегда используйте Is Nothing или IsNot Nothing.
3 голосов
/ 03 мая 2011

DateTime - тип значения , что означает, что оно всегда имеет какое-то значение.

Это как целое число - оно может быть 0 или 1, или меньше нуля, но оно никогда не может быть «ничем».

Если вы хотите, чтобы DateTime мог принимать значение Nothing, используйте Nullable DateTime.

1 голос
/ 30 декабря 2014

Вы также можете использовать ниже просто проверить:

If startDate <> Nothing Then
your logic
End If

Он проверит, является ли переменная startDate типа данных DateTime нулевым или нет.

1 голос
/ 10 апреля 2012

На любом языке программирования будьте осторожны при использовании нулей.В приведенном выше примере показана другая проблема.Если вы используете тип 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

Затем вы можете выбирать и изменять списки, чтобы сделать то, что вам нужно.Много работы - но если вам это действительно нужно, вы можете это сделать.

0 голосов
/ 20 мая 2018

Вы можете проверить это, как показано ниже:

if varDate = "#01/01/0001#" then
       '  blank date. do something.
else
       ' Date is not blank. Do some other thing
end if
0 голосов
/ 14 июля 2013

Обойти это можно было бы, используя вместо этого тип данных объекта:

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
...