Überprüfen Sie, ob einer DateTime-Variablen ein Wert zugewiesen wurde


131

Gibt es eine einfache Möglichkeit in C # zu überprüfen, ob einer DateTime-Instanz ein Wert zugewiesen wurde oder nicht?

Antworten:


82

Die einzige Möglichkeit, einer Variablen, der in C # kein Wert zugewiesen wurde, eine lokale Variable zuzuweisen, besteht darin, dass Sie beim Kompilieren feststellen können, dass sie nicht definitiv zugewiesen ist, indem Sie versuchen, daraus zu lesen: )

Ich vermute, Sie möchten wirklich Nullable<DateTime>(oder DateTime?mit dem syntaktischen C # -Zucker) - machen Sie es nullzunächst und weisen Sie dann einen normalen DateTimeWert zu (der entsprechend konvertiert wird). Dann können Sie einfach mit vergleichen null(oder die HasValueEigenschaft verwenden), um festzustellen, ob ein "realer" Wert festgelegt wurde.


Wie wäre es zu überprüfen, ob der Wert dem Standardwert für Datum und Uhrzeit entspricht? Gibt es einen nicht wahrnehmbaren Nachteil dieses Ansatzes? if (request.StartDateTime == default (DateTime) {request.StartDateTime = DateTime.Now;}
Menol

8
@Menol: Nun, das macht keinen Unterschied zwischen einem Feld, dem absichtlich der Wert gegeben wurde, default(DateTime)und einem Feld, das genau so war. Grundsätzlich wird ein Wert innerhalb der Domain als "speziell und für den normalen Gebrauch nicht verfügbar" behandelt, was mir nicht gefällt.
Jon Skeet

298

meinst du so:

DateTime datetime = new DateTime();

if (datetime == DateTime.MinValue)
{
    //unassigned
}

oder Sie könnten Nullable verwenden

DateTime? datetime = null;

 if (!datetime.HasValue)
 {
     //unassigned
 }

5
Nur die zweite davon ist kugelsicher. Die erste setzt etwas über die nicht festgelegte Darstellung einer DateTime voraus, das vom Framework nicht garantiert wird. Persönlich denke ich, dass sie für dieses Szenario ein nicht gesetztes statisches Mitglied hinzugefügt haben sollten.
Rupert Rawnsley

18
Um das hinzuzufügen, was @RupertRawnsley gesagt hat, sollten Sie tatsächlich mit dem Standardwert (DateTime) vergleichen, der der Wert einer nicht zugewiesenen DateTime ist. Es ist zufällig gleich MinValue, aber es könnte sich ändern.
Tsahi Asher

32

lege das irgendwo hin:

public static class DateTimeUtil //or whatever name
{
    public static bool IsEmpty(this DateTime dateTime)
    {
        return dateTime == default(DateTime);
    }
}

dann:

DateTime datetime = ...;

if (datetime.IsEmpty())
{
    //unassigned
}

Ich mag diese Idee, aber beachte, dass in dem etwas unwahrscheinlichen Fall, dass der DateTime-Variablen ein Wert zugewiesen wurde, der zufällig der Standardwert ist, diese Erweiterungsmethode das falsche Ergebnis zurückgibt. Die einzige Möglichkeit, dies zu vermeiden, besteht darin, eine nullbare DateTime zu verwenden, die bereits vorgeschlagen wurde. Ich mag Ihre Antwort immer noch sehr (und benutze sie jetzt), danke!
Klicker

@Klicker: Danke für deinen netten Kommentar, aber ich bin mir nicht sicher, ob ich deine Bemerkung verstehe. Soweit ich das beurteilen kann, wird == in diesem Fall immer true zurückgeben, wenn datetime dem Standardwert (DateTime) entspricht, unabhängig davon, wie datetime end-up der Standardwert zugewiesen wird. Lassen Sie mich erklären: Tatsächlich ist das zweite Snippet in meiner Antwort falsch, es wird nicht kompiliert, denn wenn Sie bedenken, dass dies der Hauptteil einer Funktion ist, ist datetime nicht zugewiesen und der Compiler wird die Verwendung ablehnen. Sie müssen ihm also einen Wert zuweisen. Es kann direkt oder indirekt die Standardeinstellung (DateTime) sein. Ich werde meine Antwort ändern.
Sonatique

und wenn in einem anderen Kontext datetime ein Mitglied einer Klasse ist und diese unverändert bleibt, weist die Laufzeit ihr die Standardeinstellung (DateTime) zu. Das == für Strukturen vergleicht tatsächlich den Inhalt der Struktur, unabhängig davon, wie die Struktur mit diesem Inhalt gefüllt ist.
Sonatique

Mein Punkt bezieht sich wirklich nur auf Klassenmitglieder, und was ich meine, ist; Wenn Sie ein DateTime-Feld oder eine DateTime-Eigenschaft auf Klassenebene haben, der Sie MinValue zugewiesen haben, gibt Ihre IsEmptyMethode true zurück, was wahrscheinlich nicht das ist, was Sie möchten (da es nicht leer ist - ihm wurde der Standardwert zugewiesen). Ich denke, der Name Ihrer Methode wäre besser geeignet als IsDefaultValue. Da kann man eigentlich keine nicht nullbare DateTime haben IsEmpty.
Klicker

@Klicker: ah ja, OK, verstanden. Sie haben Recht: Der Name, den ich gewählt habe, ist irreführend. IsDefaultValuewäre besser gewesen
Sonatique

5

DateTime ist ein Werttyp, daher kann er niemals null sein. Wenn Sie DateTime denken? (Nullable) können Sie verwenden:

DateTime? something = GetDateTime();
bool isNull = (something == null);
bool isNull2 = !something.HasValue;

5

Ich habe gerade herausgefunden, dass GetHashCode () für eine nicht zugewiesene Datumszeit immer Null ist. Ich bin nicht sicher, ob dies eine gute Möglichkeit ist, nach null datetime zu suchen, da ich keine Dokumentation dazu finden kann, warum dieses Verhalten angezeigt wird.

if(dt.GetHashCode()==0)
{
    Console.WriteLine("DateTime is unassigned"); 
} 

1
GetHashCodeGibt 0 zurück, da Ticks (interne Darstellung von DateTime) ebenfalls gleich 0 sind. Hash-Code wird folgendermaßen berechnet : unchecked((int)ticks) ^ (int)(ticks >> 32);. Siehe auch hier: referencesource.microsoft.com/#mscorlib/system/datetime.cs,836
Ivan Kochurkin

Vielen Dank. Ich versuche, eine XML-Datei aus einer C # -Klasse zu serialisieren und die Nullattribute auszuschließen. Das hat geholfen.
Jim Neff


3

Ich würde sagen, der Standardwert ist immer new DateTime(). Also können wir schreiben

DateTime datetime;

if (datetime == new DateTime())
{
    //unassigned
}

2
Diese Lösung wurde bereits 2008 von + Hath gegeben und ist, wie + Rupert Rawnsley als Kommentar hinzufügte, nicht kugelsicher ...
Roland Bär

0

Im Allgemeinen bevorzuge ich es, wenn möglich, den Standardwert von Werttypen zu verwenden, um festzustellen, ob sie festgelegt wurden. Dies ist natürlich nicht immer möglich, insbesondere bei Ints - aber für DateTimes halte ich es für fair genug, den MinValue zu reservieren, um anzuzeigen, dass er nicht geändert wurde. Dies hat gegenüber nullables den Vorteil, dass es eine Stelle weniger gibt, an der Sie eine Nullreferenzausnahme erhalten (und wahrscheinlich viele Stellen, an denen Sie vor dem Zugriff nicht auf null prüfen müssen!).


0

Wenn Sie sich nicht um Nullwertprobleme kümmern müssen, z. B. jedes Mal, wenn Sie es verwenden, nach Null suchen oder es in eine Logik einwickeln möchten, und Sie sich auch nicht um Probleme mit der Versatzzeit kümmern müssen, dann ist dies der Fall wie ich das Problem gelöst habe:

startDate = startDate < DateTime.MinValue.AddDays(1) ? keepIt : resetIt

Ich überprüfe nur, ob der Standardwert weniger als einen Tag nach Beginn der Zeit liegt. Klappt wunderbar.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.