Czy w VB.NET można ustawić DateTime
zmienną jako „nieustawiona”? I dlaczego jest to możliwe, aby ustawić DateTime
TO Nothing
, ale nie można sprawdzić, czy jest Nothing
? Na przykład:
Dim d As DateTime = Nothing
Dim boolNotSet As Boolean = d Is Nothing
Druga instrukcja generuje ten błąd:
'Is' operator does not accept operands of type 'Date'. Operands must be reference or
nullable types.
= Nothing
lub<> Nothing
nie jest dobrą praktyką: „Podczas sprawdzania, czy zmienna odwołania (lub typu wartości null ) ma wartość null , nie używaj= Nothing
lub<> Nothing
. Zawsze używajIs Nothing
lubIsNot Nothing
.”Odpowiedzi:
Jest to jedno z największych źródeł nieporozumień z VB.Net, IMO.
Nothing
w VB.Net jest odpowiednikiemdefault(T)
w C #: wartość domyślna dla danego typu.0
forInteger
,False
forBoolean
,DateTime.MinValue
forDateTime
, ...null
wartość (odwołanie, które odwołuje się do niczego).Instrukcja
d Is Nothing
jest zatem równoważna zd Is DateTime.MinValue
, która oczywiście nie jest kompilowana.Rozwiązania: jak powiedzieli inni
DateTime?
(tjNullable(Of DateTime)
.). To jest moje preferowane rozwiązanie.d = DateTime.MinValue
lub równoważnied = Nothing
W kontekście oryginalnego kodu możesz użyć:
Dim d As DateTime? = Nothing Dim boolNotSet As Boolean = d.HasValue
Bardziej wyczerpujące wyjaśnienie można znaleźć na blogu Anthony'ego D. Greena
źródło
DateTime jest typem wartości, dlatego nie może mieć wartości null. Możesz sprawdzić, czy jest równy
DateTime.MinValue
, lub możesz użyćNullable(Of DateTime)
zamiast tego.VB czasami „pomocnie” sprawia, że myślisz, że robi coś, czym nie jest. Kiedy pozwala ustawić datę na Nothing, tak naprawdę ustawia ją na inną wartość, na przykład MinValue.
Zobacz to pytanie, aby uzyskać obszerną dyskusję na temat typów wartości i typów referencyjnych.
źródło
DateTime jest typem wartości , co oznacza, że zawsze ma jakąś wartość.
Jest jak liczba całkowita - może wynosić 0, 1 lub mniej niż zero, ale nigdy nie może oznaczać „nic”.
Jeśli chcesz DateTime, który może przyjąć wartość Nothing, użyj wartości Nullable DateTime.
źródło
Kilka przykładów pracy z
DateTime
wartościami dopuszczającymi wartość null .(Zobacz Typy wartości null (Visual Basic), aby uzyskać więcej informacji).
' ' 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]
Ponadto, jak sprawdzić, czy zmienna jest null (z Nothing (Visual Basic) ):
źródło
W każdym języku programowania zachowaj ostrożność podczas używania wartości Null. Powyższy przykład pokazuje inny problem. Jeśli używasz typu Nullable, oznacza to, że zmienne, których wystąpienie pochodzi z tego typu, mogą zawierać wartość System.DBNull.Value; nie to, że zmienił interpretację ustawienia wartości na domyślną za pomocą "= Nothing" lub że obiekt wartości może teraz obsługiwać odwołanie o wartości null. Tylko ostrzeżenie ... miłego kodowania!
Możesz utworzyć oddzielną klasę zawierającą typ wartości. Obiekt utworzony z takiej klasy byłby typem referencyjnym, któremu można by przypisać Nothing. Przykład:
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
Koniec klasy
'w głównym ():
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
Następnie możesz wybrać i wybrać overridables, aby zrobić to, czego potrzebujesz. Dużo pracy - ale jeśli naprawdę tego potrzebujesz, możesz to zrobić.
źródło
Możesz również użyć poniżej, aby po prostu sprawdzić:
If startDate <> Nothing Then your logic End If
Sprawdza, czy zmienna startDate typu danych DateTime ma wartość NULL, czy nie.
źródło
Możesz to sprawdzić jak poniżej:
if varDate = "#01/01/0001#" then ' blank date. do something. else ' Date is not blank. Do some other thing end if
źródło
Sposobem na obejście tego byłoby użycie zamiast tego typu danych 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
Następnie możesz ustawić datę na inną niż ta:
MyDate = Nothing Dim theDate As Date = MyDate If theDate = Nothing Then 'date is nothing End If
źródło