Неявное приведение результата оператора Null-Coalescing

Со следующим пониманием об операторе слияния нуля (??) в C#.

int? input = -10;
int result = input ?? 10;//Case - I
//is same as:
int result = input == null? input : 10; // Case - II

Хотя, по определению и использованию, Случай I и Случай II совпадают.

Удивительно видеть, что в Case-I компилятор способен неявно приводить int? int, в то время как в случае II он показывает ошибку: "Ошибка 1 не может неявно преобразовать тип" int? " в 'int' "

Чего мне не хватает в операторе слияния?

Спасибо за ваш интерес.

4 ответа

Решение

Чтобы второй случай работал с троичным оператором, вы можете использовать следующее:

int result = input != null ? input.Value : 10;

Value собственность Nullable<T> Тип возвращает T значение (в этом случае int).

Другой вариант заключается в использовании Nullable<T>.HasValue:

int result = input.HasValue ? input.Value : 10;

myNullableInt != null конструкция является только синтаксическим сахаром для вышеупомянутого HasValue вызов.

Такое поведение вы наблюдали для оператора нуль-слияния ?? является документированной функцией языка, см. раздел 7.13 Спецификации языка C# 4.0 для получения более подробной информации.

Тип выражения b зависит от того, какие неявные преобразования доступны для операндов. В порядке предпочтения, тип b - это A0, A или B, где A - это тип a (при условии, что a имеет тип), B - это тип b (при условии, что b имеет тип), и A0 - базовый тип A, если A это обнуляемый тип, или А в противном случае. В частности, б обрабатывается следующим образом:

  • Если A существует и не является обнуляемым типом или ссылочным типом, возникает ошибка времени компиляции.

  • Если b является динамическим выражением, тип результата является динамическим. Во время выполнения a сначала оценивается. Если a не нуль, a преобразуется в динамический, и это становится результатом. В противном случае, b оценивается, и это становится результатом.

  • В противном случае, если A существует и имеет тип NULL, а неявное преобразование существует из b в A0, тип результата - A0. Во время выполнения a сначала оценивается. Если a не нуль, a разворачивается к типу A0, и это становится результатом. В противном случае b вычисляется и преобразуется в тип A0, и это становится результатом.

  • В противном случае, если A существует и существует неявное преобразование из b в A, тип результата - A. Во время выполнения a сначала оценивается. Если a не нуль, a становится результатом. В противном случае b вычисляется и преобразуется в тип A, и это становится результатом.

  • В противном случае, если b имеет тип B и существует неявное преобразование из a в B, тип результата - B. Во время выполнения a сначала оценивается. Если a не является нулем, a разворачивается в тип A0 (если A существует и допускает обнуление) и преобразуется в тип B, и это становится результатом. В противном случае, b оценивается и становится результатом.

  • В противном случае, a и b несовместимы, и возникает ошибка времени компиляции.

Смотрите раздел 7.14, почему условный оператор a ? b : c работает по другому.

Загрузите спецификацию, чтобы прочитать оба в полном объеме на досуге.

int result = input == null ? input : 10;

Во втором случае у вас смешанное состояние - вы, вероятно, имели в виду:

int result = input != null ? input : 10;

Теперь это не скомпилируется, потому что оба типа, используемые с троичным оператором, должны быть точно идентичными (и int? это не то же самое, что int) - вы можете использовать простое приведение в качестве решения:

int result = input != null ? (int)input : 10;

Более краткое объяснение:

int? NULL_Int = 1;
int NORM_Int = 2;

NULL_Int = NORM_Int;  // OK

NORM_Int = NULL_Int;  // NO, you can't assign a null to an int
Другие вопросы по тегам