Почему я не могу проверить, является ли "дата-время ""ничем"?


In 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 67

8 ответов:

это один из самых больших источников путаницы с VB.Net ИМО.

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

  • для типов значений, это по сути эквивалент "ноль": 0 на Integer,False на Boolean,DateTime.MinValue на DateTime, ...
  • для ссылочных типов, это null значение (ссылка, которая ссылается на, ну, ничего).

в заявление эквивалентно d Is DateTime.MinValue, который, очевидно, не компилируется.

решения: как говорили другие

  • использовать DateTime? (т. е. Nullable(Of DateTime)). Это мое предпочтительное решение.
  • или использовать d = DateTime.MinValue или d = Nothing

в контексте исходного кода, Вы можете использовать:

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

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

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

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

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

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

При проверке того, является ли ссылочная (или nullable value type) переменная null не используйте = Nothing или <> Nothing. Всегда используйте Is Nothing или IsNot Nothing.

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

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

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

в любом языке программирования, будьте осторожны при использовании нулями. В приведенном выше примере показана еще одна проблема. Если вы используете тип Nullable, это означает, что переменные, созданные из этого типа, могут содержать систему значений.Значение dbnull.Значение; не то, что он изменил интерпретацию установки значения по умолчанию с помощью "= 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

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

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

If startDate <> Nothing Then
your logic
End If

он будет проверять, что переменная startDate типа DateTime имеет значение null или нет.

способ обойти это было бы использовать тип объекта:

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 varDate = "#01/01/0001#" then
       '  blank date. do something.
else
       ' Date is not blank. Do some other thing
end if