Почему этот код C # не компилируется?

double? test = true ? null : 1.0;

В моей книге это то же самое, что и

if (true) {
  test = null;
} else {
  test = 1.0;
}

Но первая строка дает эту ошибку компилятора:

Тип условного выражения не может быть определен, потому что между «<null>» и «double» нет неявного преобразования.

Ответ 1

Это происходит потому, что компилятор пытается оценить оператор справа налево. Это означает, что он видит 1.0, и он решает, что он двойной (не двойной?), А затем видит null.

Таким образом, явно нет никакого неявного преобразования между double и null (на самом деле нет неявного преобразования между Struct и null).

Что вы можете сделать, это явно указать компилятору, что одно из двух выражений, которые конвертируются друг в друга.

double? test = true ? null : (double?) 1.0;    // 1
double? test = true ? (double?)null : 1.0;     // 2
double? test = true ?  default(double?) : 1.0; // 3
double? test = true ? new double?() : 1.0;     // 4

Ответ 2

double? test = true ? (double?)null : 1.0;

будет работать. Это потому, что нет преобразования из типа первого выражения (null) в тип второго выражения (double).

Ответ 3

Левая часть присваивания не используется при выводе типа выражения?:.

В b ? A : B типы A и B должны либо быть одинаковыми, либо должны быть неявно конвертируемыми в другие.

Ответ 4

Поскольку компилятор не может понять, что для нулевого и 1.0 для совместимости, значения должны быть выбраны в double ?. Это должно быть четко указано.

double? test = true ? (double?) null : 1.0;