Неявное приведение результата оператора 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