Czy ktoś mógłby wyjaśnić, dlaczego to działa w C # .NET 2.0:
Nullable<DateTime> foo;
if (true)
foo = null;
else
foo = new DateTime(0);
... ale to nie:
Nullable<DateTime> foo;
foo = true ? null : new DateTime(0);
Druga forma powoduje błąd kompilacji „Nie można określić typu wyrażenia warunkowego, ponieważ nie ma niejawnej konwersji między '<null>' i 'System.DateTime'.”
Nie to, że nie mogę użyć pierwszego, ale drugi styl jest bardziej spójny z resztą mojego kodu.
c#
generics
nullable
conditional-operator
Nick Gotch
źródło
źródło
Odpowiedzi:
To pytanie zadawano już kilka razy. Kompilator mówi ci, że nie wie, jak przekonwertować
null
plikDateTime
.Rozwiązanie jest proste:
Zauważ, że
Nullable<DateTime>
można napisać,DateTime?
co pozwoli Ci zaoszczędzić sporo pisania.źródło
<null>
aDateTime
i zamiast znalezienia wspólnego przodka rodzaju, po prostu próbuje znaleźć konwersję między sobą. (Dodatkowy bit: C # rozpoznaje<null>
typ, tj. Typ każdegonull
wyrażenia.)FYI (Offtopic, but sprytny i powiązany z typami dopuszczającymi wartość null) mamy przydatny operator tylko dla typów dopuszczających wartość null zwany null coalescing operator
Używane w ten sposób:
źródło
Dzieje się tak, ponieważ w operatorze trójargumentowym dwie wartości muszą być rozstrzygane na ten sam typ.
źródło
Wiem, że to pytanie padło w 2008 roku, a teraz jest 5 lat później, ale odpowiedź oznaczona jako odpowiedź mnie nie satysfakcjonuje. Prawdziwą odpowiedzią jest to, że DateTime jest strukturą i jako struktura nie jest zgodna z wartością null. Masz dwa sposoby rozwiązania tego problemu:
Po pierwsze, należy uczynić null kompatybilnym z DateTime (na przykład rzut null na DateTime ?, jak sugeruje dżentelmen z 70 upvotes, lub rzut null na Object lub ValueType).
Drugim jest zapewnienie zgodności DateTime z wartością null (na przykład rzutowanie DateTime na DateTime?).
źródło
Innym rozwiązaniem podobnym do przyjętego jest użycie
default
słowa kluczowego C # . Chociaż jest zdefiniowany przy użyciu typów ogólnych, w rzeczywistości ma zastosowanie do każdego typu.Przykładowe użycie zastosowane do pytania PO:
Przykładowe użycie z aktualnie zaakceptowaną odpowiedzią:
Ponadto, korzystając z
default
, nie musisz określać zmiennej jakonullable
, aby przypisać jejnull
wartość. Kompilator automatycznie przypisze domyślną wartość określonego typu zmiennej i nie zostanie napotkany żaden błąd. Przykład:źródło
default(DateTime)
nie jest zerowa, to jest "1.1.0001 0:00:00
" to samo conew DateTime(0)
.null
, tylko że używającdefault()
możesz przypisać go donullable
wartości (jak stwierdza MSDN). Przykłady pokazują, że wykazują różnorodność, która może być używana zNullable<DateTime>
,DateTime?
i po prostuDateTime
. Jeśli uważasz, że to nieprawda, czy możesz dostarczyć dokument PoC, jeśli te zawiodły?null
w zmiennej, niedefault(DateTime)
, więc jest to w najlepszym przypadku mylące. To nie jest „uniwersalny”, jak sugerujesz, ponieważ wyrażenie jako całość ma jeszcze tego samego typu -DateTime
i można zastąpićdefault(DateTime)
znew DateTime()
i będzie robić to samo. Możedefault(DateTime?)
to miałeś na myśli, skoro tak naprawdę jest to równenull
.