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

В С# почему оператор условного оператора неявно не вводится в тип с нулевым значением

Мне любопытно, почему неявный листинг терпит неудачу в...

int? someValue = SomeCondition ? ResultOfSomeCalc() : null;

и почему я должен выполнить явное преобразование вместо

int? someValue = SomeCondition ? ResultofSomeCalc() : (int?)null;

Мне кажется, что у компилятора есть вся информация, необходимая для принятия неявного решения о литье, нет?

4b9b3361

Ответ 1

Соответствующий раздел спецификации С# 3.0 равен 7.13, условный оператор:

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

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

Ответ 2

Меня также раздражает, что он не может вывести тип, основанный на назначении, особенно когда он тип значения. Есть причины, когда вы попадаете в геральдические объекты.

Если "ResultOfSomeCalc()" вернул "int?", тогда это будет работать. С# нужно выяснить тип независимо от того, что находится слева от задания. Таким образом, вы говорите ему, что вы вернете нуль или int, и логики в компиляторе не существует, чтобы он заменил Nullable как общий знаменатель.

Обратите внимание, что эти варианты DO работают, и это может помочь вам понять:

object someValue = true ? new Nullable<int>(ResultOfSomeCalc()) : null;

object someValue = true ? (int?)ResultOfSomeCalc() : null;

Надеюсь, что это поможет.

Ответ 3

Кажется, что это то, что компилятор должен понять, но есть еще один способ сделать это, используя ключевое слово по умолчанию. Это может быть самый маленький бит, менее уродливый, чем приведение:

int? someValue = SomeCondition ? ResultofSomeCalc() : default(int?);

Это использование дефолта, похоже, не хорошо документировано, но работает. По крайней мере, это мешает вам помешать вашему коду волшебными значениями (я утверждаю, что null/zero/false/etc) действительно волшебные значения).

Ответ 5

Если ваша функция ResultofSomeCalc() возвращает int? то это будет работать.

Если ваша функция возвращает int, компилятор выдает предупреждение:   Тип условного выражения не может быть определен, потому что нет никакого неявного преобразования между 'int' и '' Я предполагаю, что это то, что вы видите. Оба выражения в условном операторе "?:" Должны иметь один и тот же тип или должны быть конвертированы в один и тот же тип с помощью неявного литья.

Измените возвращаемый тип ResultOfSomeCalc на int?, или вам нужно будет иметь приведение в нулевое выражение.

Ответ 6

Сделайте свою функцию ResultOfSomeCalc() возвращаемым типом как nullabel int like (int?)
Int? someValue = (int?) SomeCondition? ResultofSomeCalc(): (int?) Null;