Неявное приведение результата оператора Null-Coalescing - PullRequest
6 голосов
/ 17 января 2012

При следующем понимании оператора объединения нулей (??) в 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 ]

5 голосов
/ 17 января 2012

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

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

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

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

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

  • В противном случае, если существует A и существует неявное преобразование из b в 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 работает по-другому.

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

5 голосов
/ 17 января 2012

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

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.

0 голосов
/ 17 января 2012

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

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
0 голосов
/ 17 января 2012
int result = input == null ? input : 10;

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

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

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

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