Подтвердить что ты не робот

Почему null нужен явный тип приведения здесь?

Следующий код не компилируется:

//int a = ...
int? b = (int?) (a != 0 ? a : null);

Для компиляции его необходимо изменить на

int? b = (a != 0 ? a : (int?) null);

Поскольку оба b = null и b = a являются законными, для меня это не имеет смысла.

Почему нам нужно отбрасывать null в int? и почему мы не можем просто предоставить явный тип для всего выражения (что, как я знаю, возможно в других случаях)?

4b9b3361

Ответ 1

Из раздела 7.13 Спецификации языка С#:

Второй и третий операнды оператора?: управляют типом условного выражения. Пусть X и Y - типы второго и третьего операндов. Тогда,

  • Если X и Y являются одним и тем же типом, то это тип условного выражения.
  • В противном случае, если неявное преобразование (§6.1) существует из X в Y, но не от Y до X, то Y является типом условного выражения.
  • В противном случае, если неявное преобразование (§6.1) существует от Y до X, но не от X до Y, то X является типом условного выражения.
  • В противном случае тип выражения не может быть определен, и возникает ошибка времени компиляции.

В вашем случае нет никакого неявного преобразования из int в null или наоборот. Ваш бросок решает проблему, int преобразуется в int?

Ответ 2

Обе альтернативы оператора ?: должны быть одного типа. В противном случае компилятор не может вывести тип всего условного выражения.

null не является int, поэтому вам нужно дать подсказку компилятору, что результирующий тип int?.


Изменить: как указывали другие, два типа не обязательно должны быть одинаковыми, но один из них должен быть привязан к другому (другой будет типом результата). Подробнее см. спецификации.

Ответ 3

Вы можете спасти себя от кастинга, если вы используете default(int?) вместо null.

int a = 42;
int? b = (a != 0 ? a : default(int?));

Ответ 4

потому что, когда вы используете такую ​​нотацию, оба члена должны быть одного типа, поэтому вам нужно явно сказать "этот член является int?".

ясно?

Ответ 5

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

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

В вашем случае как int, так и null требуется, чтобы неявные преобразования стали int?, поэтому он не работает.
Вам нужно изменить код, чтобы одна сторона была int?, а другая сторона была неявно преобразована в int?. Простейший способ сделать это - заменить null на new int?() следующим образом:

int? b = (a != 0 ? a : new int?());

Для этого требуется только одно неявное преобразование (int to int?).

Ответ 6

Это почти дубликат одного моих вопросов относительно условного оператора. Это не нуль, это действительно :.

Ответ, принятый там, довольно хорош, не кто иной, как Эрик Липперт, который находится в команде компилятора С#.