Dlaczego nie mogę sprawdzić, czy 'DateTime' to 'nic'?

W VB.NET, czy istnieje sposób na ustawienie zmiennej DateTime na "not set"? I dlaczego można ustawić DateTime na Nothing, Ale nie można sprawdzić, czy jest? Na przykład:

Dim d As DateTime = Nothing
Dim boolNotSet As Boolean = d Is Nothing 

Drugie stwierdzenie wyrzuca ten błąd:

'Is' operator does not accept operands of type 'Date'. Operands must be reference or
nullable types.
Author: DavidRR, 2011-05-03

8 answers

Jest to jedno z największych źródeł zamieszania z VB.Net, IMO.

Nothing w VB.Net jest odpowiednikiem default(T) W C#: domyślna wartość dla danego typu.

  • dla typów wartości jest to zasadniczo odpowiednik 'zero': 0 dla Integer, False na Boolean, DateTime.MinValue dla DateTime,...
  • dla typów referencyjnych jest to wartość null (odniesienie, które odnosi się do, cóż, nic).

Twierdzenie d Is Nothing jest więc równoważne d Is DateTime.MinValue, które oczywiście nie kompiluje.

Rozwiązania: jak mówili inni

  • albo użyć DateTime? (tj. Nullable(Of DateTime)). To jest moje preferowane rozwiązanie.
  • lub użyć {[14] } lub równoważnie d = Nothing

W kontekście oryginalnego kodu można użyć:

Dim d As DateTime? = Nothing
Dim boolNotSet As Boolean = d.HasValue
Bardziej obszerne Wyjaśnienie można znaleźć na blogu Anthony ' ego D. Greena
 140
Author: jeroenh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-20 20:10:27

DateTime jest typem wartości, dlatego nie może być null. Możesz sprawdzić, czy jest równa DateTime.MinValue, lub zamiast tego możesz użyć Nullable(Of DateTime).

VB czasami" pomocnie " sprawia, że myślisz, że robi coś, czym nie jest. Kiedy pozwala ustawić datę na nic, to tak naprawdę ustawia ją na inną wartość, może MinValue.

Zobacz to pytanie , aby uzyskać obszerne omówienie typów wartości a typów referencyjnych.

 12
Author: John M Gant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:08

DateTime jest typem wartości , co oznacza, że zawsze ma jakąś wartość.

To jest jak liczba całkowita - może być 0, lub 1, lub mniej niż zero, ale nigdy nie może być "nic".

Jeśli chcesz DateTime, który może przyjmować wartość Nothing, użyj Nullable DateTime.

 4
Author: Cheeso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-03 12:50:22

Kilka przykładów pracy z wartościami nullable DateTime.

(Zobacz typy wartości Nullable (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]

Również, jak sprawdzić, czy zmienna jest null (z Nothing (Visual Basic)):

Podczas sprawdzania, czy zmienna reference (lub nullable value type) to null , nie używaj = Nothing ani <> Nothing. Zawsze używaj Is Nothing lub IsNot Nothing.
 4
Author: DavidRR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-13 01:10:52

W dowolnym języku programowania należy zachować ostrożność podczas używania null. Powyższy przykład pokazuje inny problem. Jeśli używasz typu Nullable, oznacza to, że zmienne utworzone z tego typu mogą przechowywać system wartości.DBNull.Wartość; nie to, że zmieniła interpretację ustawienia wartości na domyślną za pomocą "= Nothing " lub że obiekt wartości może teraz obsługiwać odniesienie null. Tylko Ostrzeżenie... szczęśliwego kodowania!

Można utworzyć osobną klasę zawierającą typ wartości. Obiekt utworzony z takiej klasy byłby typem odniesienia, któremu nie można by nic przypisać. 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

End Class

" W 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

Następnie możesz wybrać i wybrać overridables, aby zrobił to, czego potrzebujesz. Dużo pracy - ale jeśli naprawdę jej potrzebujesz, możesz to zrobić.

 1
Author: sscheider,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-10 17:26:41

Możesz również użyć poniższego prostego do sprawdzenia:

If startDate <> Nothing Then
your logic
End If

Sprawdzi czy zmienna startDate Datatime datatype jest null czy nie.

 1
Author: Mahavirsinh Padhiyar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-30 12:18:13

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
 1
Author: Sukhi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-19 21:37:43

Sposobem obejścia tego problemu byłoby użycie obiektu datatype zamiast:

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

Wtedy możesz ustawić datę na nic takiego:

MyDate = Nothing
Dim theDate As Date = MyDate
If theDate = Nothing Then
    'date is nothing
End If
 0
Author: George Filippakos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-14 22:12:21