Könnte jemand erklären, warum dies in C # .NET 2.0 funktioniert:
Nullable<DateTime> foo;
if (true)
foo = null;
else
foo = new DateTime(0);
... aber das geht nicht:
Nullable<DateTime> foo;
foo = true ? null : new DateTime(0);
Das letztere Formular gibt mir einen Kompilierungsfehler. "Der Typ des bedingten Ausdrucks kann nicht bestimmt werden, da keine implizite Konvertierung zwischen '<null>' und 'System.DateTime' erfolgt."
Nicht, dass ich den ersteren nicht verwenden kann, aber der zweite Stil stimmt besser mit dem Rest meines Codes überein.
c#
generics
nullable
conditional-operator
Nick Gotch
quelle
quelle
Antworten:
Diese Frage wurde bereits einige Male gestellt. Der Compiler sagt Ihnen, dass er nicht weiß, wie er
null
in einen konvertiertDateTime
.Die Lösung ist einfach:
Beachten Sie, dass
Nullable<DateTime>
dies geschriebenDateTime?
werden kann, wodurch Sie eine Menge Tipparbeit sparen.quelle
<null>
undDateTime
und anstatt den gemeinsamen Ahnen-Typ zu finden, versucht es nur, eine Konvertierung untereinander zu finden. (Extra-Bit: C # erkennt einen<null>
Typ, dh den Typ jedesnull
Ausdrucks.)Zu Ihrer Information (Offtopic, aber geschickt und verwandt mit nullbaren Typen) haben wir einen praktischen Operator nur für nullbare Typen, den Null-Koaleszenz-Operator
So verwendet:
quelle
Dies liegt daran, dass in einem ternären Operator die beiden Werte in denselben Typ aufgelöst werden müssen.
quelle
Ich weiß, dass diese Frage im Jahr 2008 gestellt wurde und es nun 5 Jahre später ist, aber die als Antwort gekennzeichnete Antwort befriedigt mich nicht. Die eigentliche Antwort lautet, dass DateTime eine Struktur ist und als Struktur nicht mit null kompatibel ist. Sie haben zwei Möglichkeiten, dies zu lösen:
Zunächst muss null mit DateTime kompatibel gemacht werden (z. B. null in DateTime umwandeln, wie der Gentleman mit 70 positiven Stimmen vorschlägt, oder null in Object oder ValueType umwandeln).
Die zweite besteht darin, die DateTime mit null kompatibel zu machen (z. B. DateTime in DateTime umwandeln?).
quelle
Eine andere ähnliche Lösung wie die akzeptierte besteht darin, das
default
Schlüsselwort von C # zu verwenden . Während es mit Generika definiert wird, ist es tatsächlich auf jeden Typ anwendbar.Anwendungsbeispiel für die Frage des OP:
Anwendungsbeispiel mit der aktuell akzeptierten Antwort:
Bei Verwendung von
default
müssen Sie die Variable auch nicht wie angegeben angebennullable
, um ihr einennull
Wert zuzuweisen . Der Compiler weist den Standardwert des jeweiligen Variablentyps automatisch zu, und es tritt kein Fehler auf. Beispiel:quelle
default(DateTime)
ist nicht null, es ist "1.1.0001 0:00:00
", das gleiche wienew DateTime(0)
.null
, nur dassdefault()
Sie es mithilfe von verwenden können, um es einemnullable
Wert zuzuweisen (wie MSDN angibt). Die Beispiele , die ich zeigen , demonstrieren die Vielseitigkeit , die sie mit verwendet werden kannNullable<DateTime>
,DateTime?
und einfachDateTime
. Wenn Sie der Meinung sind, dass dies falsch ist, können Sie einen PoC bereitstellen, bei dem diese fehlschlagen?null
in der Variablen speichern , nichtdefault(DateTime)
, also ist dies bestenfalls irreführend. Dies ist nicht „vielseitig“ , wie Sie implizieren, da der Ausdruck als Ganzes noch die gleiche Art hat -DateTime
und Sie können ersetzendefault(DateTime)
mitnew DateTime()
und es wird das gleiche tun. Vielleicht habendefault(DateTime?)
Sie das gemeint, denn das ist eigentlich gleichnull
.