Почему я не могу проверить, является ли "DateTime" "Nothing"?
В VB.NET существует ли способ установить переменную DateTime
в значение "not set"? И почему можно установить 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.
Ответы
Ответ 1
Это один из самых больших источников путаницы с VB.Net, IMO.
Nothing
в VB.Net является эквивалентом default(T)
в С#: значение по умолчанию для данного типа.
- Для типов значений это по существу эквивалентны нулю:
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
Ответ 2
DateTime - это тип значения, поэтому он не может быть нулевым. Вы можете проверить, чтобы он был равен DateTime.MinValue
, или вы можете использовать Nullable(Of DateTime)
вместо этого.
VB иногда "помогает" заставляет вас думать, что он что-то делает. Когда он позволяет вам установить дату в "Нет", она действительно устанавливает ее на какое-то другое значение, возможно, MinValue.
См. этот вопрос для подробного обсуждения типов значений по сравнению с ссылочными типами.
Ответ 3
Некоторые примеры работы с значениями с нулевым значением DateTime
.
(Подробнее см. Nullable Value Types (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 (из Nothing (Visual Basic)):
При проверке того, является ли ссылочная (или нулевая тип типа значения) null, не используйте = Nothing
или <> Nothing
. Всегда используйте Is Nothing
или IsNot Nothing
.
Ответ 4
DateTime - это тип значения, что означает, что он всегда имеет некоторое значение.
Это как целое число - оно может быть 0 или 1 или меньше нуля, но никогда не может быть "ничего".
Если вы хотите использовать DateTime, который может принимать значение Nothing, используйте Nullable DateTime.
Ответ 5
На любом языке программирования будьте осторожны при использовании Nulls. В приведенном выше примере показана другая проблема. Если вы используете тип 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
Затем вы можете выбрать и переопределить, чтобы сделать то, что вам нужно. Много работы - но если вам это действительно нужно, вы можете это сделать.
Ответ 6
Вы также можете использовать ниже, просто чтобы проверить:
If startDate <> Nothing Then
your logic
End If
Он будет проверять, что переменная startDate типа данных DateTime имеет значение null или нет.
Ответ 7
В этом случае вместо этого следует использовать тип данных 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