Почему я не могу проверить, является ли "дата-время ""ничем"?
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 ответов:
это один из самых больших источников путаницы с 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