Почему это не компилируется?
int? number = true ? 5 : null;
Тип условного выражения не может быть определен, поскольку не существует неявного преобразования между int и <null>
Почему это не компилируется?
int? number = true ? 5 : null;
Тип условного выражения не может быть определен, поскольку не существует неявного преобразования между int и <null>
Ответы:
Спецификация (§7.14) гласит, что для условного выражения b ? x : yсуществует три возможности, xи yоба имеют тип и выполняются определенные хорошие условия , только один из xи yимеет тип, и определенные хорошие условия выполняются, или ошибка времени компиляции происходит. Здесь «определенные хорошие условия» означают, что возможны определенные преобразования, о которых мы поговорим ниже.
Теперь давайте обратимся к немецкой части спецификации:
Если только один из
xиyимеет тип, и оба,xиyнеявно преобразуются в этот тип, то это тип условного выражения.
Проблема здесь в том, что в
int? number = true ? 5 : null;
только один из условных результатов имеет тип. Вот xэто intбуквально, и yэто nullкоторый не не имеют типа и nullне неявно раскладывается в int1 . Следовательно, «определенные хорошие условия» не выполняются, и возникает ошибка времени компиляции.
Там являются два пути вокруг этого:
int? number = true ? (int?)5 : null;
Здесь мы все еще в случае, когда только один из xи yимеет тип. Обратите внимание , что до null сих пор не имеет типа пока компилятор не будет иметь никаких проблем с этим , потому что (int?)5и nullоба неявно преобразованы в int?(§6.1.4 и §6.1.5).
Другой способ, очевидно,
int? number = true ? 5 : (int?)null;
но теперь мы должны прочитать другой пункт в спецификации, чтобы понять, почему это нормально:
Если
xимеет типXиyимеет тип,Yто
Если неявное преобразование (§6.1) существует из
XtoY, но не изYtoX, тогдаYэто тип условного выражения.Если неявное преобразование (§6.1) существует из
YtoX, но не изXtoY, тогдаXэто тип условного выражения.В противном случае тип выражения не может быть определен, и возникает ошибка времени компиляции.
Вот xтипа intи yтипа int?. Там нет неявного преобразования int?к int, но есть неявное преобразование intк int?такому типу выражения int?.
1 : Отметим далее, что тип левой части игнорируется при определении типа условного выражения, что является распространенным источником путаницы.
new int?()на месте (int?)null.
DateTime, когда это потребуется,(DateTime?)
null не имеет идентифицируемого типа - просто нужно немного подтолкнуть его, чтобы сделать его счастливым:
int? number = true ? 5 : (int?)null;
int? number = true ? 5 : null as int?;
int? number = true ? 5 : (int?)null;и int? number = true ? (int?)5 : null;как компиляции !! Царапина, царапина
Как уже упоминали другие, 5 является int, и nullне может быть неявно преобразовано в int.
Вот другие способы обойти эту проблему:
int? num = true ? 5 : default(int?);
int? num = true ? 5 : new int?();
int? num = true ? 5 : null as int?;
int? num = true ? 5 : (int?)null;
int? num = true ? (int?)5 : null;
int? num = true ? 5 as int? : null;
int? num = true ? new int?(5) : null;
Кроме того, везде, где вы видите int?, вы также можете использовать Nullable<int>.
В C# 9этом сейчас разрешен блог
Цель набрана ?? и ?
Иногда условно и?: выражения не имеют очевидного общего типа между ветвями. Такие случаи сегодня терпят неудачу, но C # 9.0 разрешит их, если есть целевой тип, в который преобразуются обе ветви:
Person person = student ?? customer; // Shared base type
int? result = b ? 0 : null; // nullable value type
Или ваш пример:
// Allowed in C# 9.
int? number = true ? 5 : null;