Проблема типа Nullable с?: Условный оператор - PullRequest
149 голосов
/ 17 ноября 2008

Может кто-нибудь объяснить, почему это работает в C # .NET 2.0:

    Nullable<DateTime> foo;
    if (true)
        foo = null;
    else
        foo = new DateTime(0);

... но это не так:

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

Последняя форма дает мне ошибку компиляции: «Тип условного выражения не может быть определен, поскольку не существует неявного преобразования между« »и« System.DateTime »."

Не то, чтобы я не мог использовать первый, но второй стиль больше соответствует остальной части моего кода.

Ответы [ 5 ]

315 голосов
/ 17 ноября 2008

Этот вопрос уже задавался несколько раз. Компилятор говорит вам, что не знает, как конвертировать null в DateTime.

Решение простое:

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

Обратите внимание, что Nullable<DateTime> может быть написано DateTime?, что сэкономит вам кучу текста.

19 голосов
/ 17 ноября 2008

FYI (оффтоп, но изящный и связанный с обнуляемыми типами) у нас есть удобный оператор только для обнуляемых типов, называемый оператором слияния нуль

??

Используется так:

// Left hand is the nullable type, righthand is default if the type is null.
Nullable<DateTime> foo;
DateTime value = foo ?? new DateTime(0);
8 голосов
/ 17 ноября 2008

Это потому, что в троичном операторе эти два значения должны разрешаться в один и тот же тип.

4 голосов
/ 27 августа 2012

Другое решение, подобное принятому, заключается в использовании ключевого слова C # default. Хотя он определен с использованием обобщений, он фактически применим к любому типу.

Пример использования, примененный к вопросу ОП:

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

Пример использования с текущим принятым ответом:

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

Также, используя default, вам не нужно указывать переменную как nullable, чтобы присвоить ей значение null. Компилятор автоматически назначит значение по умолчанию для определенного типа переменной, и ошибки не возникнет. Пример:

DateTime foo;
foo = true ? default(DateTime) : new DateTime(0);
3 голосов
/ 08 апреля 2013

Я знаю, что этот вопрос задавался в 2008 году, а сейчас - 5 лет спустя, но ответ, помеченный как ответ, меня не удовлетворяет. Реальный ответ заключается в том, что DateTime - это структура, и как структура она не совместима с нулем. У вас есть два способа решения этой проблемы:

Сначала необходимо сделать NULL совместимым с DateTime (например, привести NULL к DateTime?, Как предполагает джентльмен с 70 голосами вверх, или NULL для Object или ValueType).

Второй - сделать DateTime совместимым с нулевым значением (например, приведение DateTime к DateTime?).

...