Неверный тип проблемы с?: Условный оператор
Может кто-нибудь объяснить, почему это работает в С#.NET 2.0:
Nullable<DateTime> foo;
if (true)
foo = null;
else
foo = new DateTime(0);
... но это не так:
Nullable<DateTime> foo;
foo = true ? null : new DateTime(0);
Последняя форма дает мне ошибку компиляции. "Тип условного выражения не может быть определен, потому что нет никакого неявного преобразования между" <null> "; и" System.DateTime".
Не то, чтобы я не мог использовать первое, но второй стиль более соответствует остальной части моего кода.
Ответы
Ответ 1
Этот вопрос задавали уже несколько раз. Компилятор сообщает вам, что он не знает, как преобразовать null
в DateTime
.
Решение прост:
DateTime? foo;
foo = true ? (DateTime?)null : new DateTime(0);
Обратите внимание, что Nullable<DateTime>
может быть записано DateTime?
, что спасет вас от набора символов.
Ответ 2
FYI (Offtopic, но отличный и связанный с типами NULL), мы имеем удобный оператор только для типов с нулевым значением, называемый нулевым коалесцирующим оператором
??
Используется следующим образом:
// Left hand is the nullable type, righthand is default if the type is null.
Nullable<DateTime> foo;
DateTime value = foo ?? new DateTime(0);
Ответ 3
Это потому, что в тернарном операторе два значения должны быть разрешены для одного и того же типа.
Ответ 4
Другим решением, аналогичным принятому, является использование ключевого слова С# default
. Хотя он определен с использованием дженериков, он действительно применим к любому типу.
Пример использования приложения к вопросу OP:
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);
Ответ 5
Я знаю, что этот вопрос был задан в 2008 году, а сейчас 5 лет спустя, но ответ, отмеченный как ответ, не удовлетворяет меня. Реальный ответ заключается в том, что DateTime является структурой, а в качестве структуры он несовместим с нулем. У вас есть два способа решить это:
Сначала нужно сделать null совместимым с DateTime (например, отбрасывать null до DateTime? как говорит джентльмен с 70 upvotes или отличать null от Object или ValueType).
Во-вторых, сделать DateTime совместимым с нулевым (например, придать DateTime DateTime?).