Почему это не компилируется?
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
неявно конвертируется в int
1. Поэтому "определенные хорошие условия" не выполняются, и возникает ошибка времени компиляции.
Существует два способа:
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) существует от
x
доy
, но не отy
доx
, тоy
является типом условного выражения.Если неявное преобразование (§6.1) существует от
y
доx
, но не отx
доy
, тоx
является типом условного выражения.В противном случае тип выражения не может быть определен, и возникает ошибка времени компиляции.
Здесь x
имеет тип int
и y
имеет тип int?
. Нет неявного преобразования из int?
в int
, но есть неявное преобразование от int
до int?
, поэтому тип выражения int?
.
1: Обратите внимание, что тип левой части игнорируется при определении типа условного выражения, что является общим источником путаницы.
null
не имеет идентифицируемого типа - ему просто нужно немного подталкивать, чтобы сделать его счастливым:
int? number = true ? 5 : (int?)null;