В C # почему условный оператор не может неявно приводиться к обнуляемому типу - PullRequest
30 голосов
/ 21 октября 2008

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

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

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

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

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

Ответы [ 6 ]

27 голосов
/ 21 октября 2008

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

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

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

15 голосов
/ 21 октября 2008

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

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

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

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

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

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

5 голосов
/ 07 февраля 2009

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

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

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

4 голосов
/ 21 октября 2008
0 голосов
/ 14 апреля 2015

Сделайте так, чтобы ваша функция возвращала тип результата ResultOfSomeCalc () как nullabel int like (int?)
Int? someValue = (int?) SomeCondition? ResultofSomeCalc (): (int?) Null;

0 голосов
/ 21 октября 2008

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

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

Измените тип возвращаемого значения ResultOfSomeCalc на int? Или вам нужно будет привести приведение к нулевому выражению.

...