Problem typu Nullable z: operatorem warunkowym

Mógłby ktoś 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);

Ta ostatnia forma daje mi błąd kompilacji " nie można określić typu wyrażenia warunkowego, ponieważ nie ma ukrytej konwersji między '' i 'System.DateTime"."

Nie żebym nie mógł użyć pierwszego, ale drugi styl jest bardziej zgodny z resztą mojego kodu.

Author: Nick Gotch, 2008-11-17

5 answers

To pytanie było już zadawane kilka razy. Kompilator mówi ci, że nie wie jak przekształcić null w DateTime.

Rozwiązanie jest proste:

DateTime? foo;
foo = true ? (DateTime?)null : new DateTime(0);

Zauważ, że Nullable<DateTime> można zapisać DateTime?, co zaoszczędzi ci sporo pisania.

 303
Author: Stewart Johnson,
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
2008-11-17 15:34:39

FYI (Offtopic, ale sprytny i związany z typami nullable) mamy poręczny operator tylko dla typów nullable zwany operatorem koalescencyjnym null

??

Używane w ten sposób:

// Left hand is the nullable type, righthand is default if the type is null.
Nullable<DateTime> foo;
DateTime value = foo ?? new DateTime(0);
 18
Author: FlySwat,
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
2008-11-17 15:43:03

Dzieje się tak dlatego, że w operatorze trójdzielnym obie wartości muszą być rozdzielone na ten sam typ.

 8
Author: MojoFilter,
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
2016-03-29 02:00:30

Innym rozwiązaniem podobnym do przyjętego jest użycie C#'s default słowo kluczowe. Chociaż zdefiniowany za pomocą leków generycznych, w rzeczywistości ma zastosowanie do każdego typu.

Przykład użycia zastosowanego do pytania OP:

Nullable<DateTime> foo;
foo = true ? default(DateTime) : new DateTime(0);

Przykładowe użycie z aktualną akceptowaną odpowiedzią:

DateTime? foo;
foo = true ? default(DateTime) : new DateTime(0);

Ponadto, używając default, nie musisz określać zmiennej jako nullable, aby przypisać jej wartość null. Kompilator automatycznie przypisze domyślną wartość określonego typu zmiennej i żaden błąd nie spowoduje być napotkanym. Przykład:

DateTime foo;
foo = true ? default(DateTime) : new DateTime(0);
 5
Author: newfurniturey,
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-11-04 01:28:33

Wiem, że to pytanie zadano w 2008 roku, a teraz jest 5 lat później, ale odpowiedź oznaczona jako odpowiedź mnie nie zadowala. Prawdziwa odpowiedź jest taka, że DateTime jest strukturą i jako struktura nie jest zgodna z null. Można to rozwiązać na dwa sposoby:

Pierwszy polega na tym, aby null był zgodny z DateTime (na przykład, cast null to DateTime? jak sugeruje gentleman z 70 upvotes, lub cast null to Object or to ValueType).

Drugim jest zapewnienie zgodności DateTime z null (na przykład, cast DateTime to DateTime?).

 3
Author: Mishax,
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-04-07 22:28:40