Я запутался с компилятором c # в случае отрицания null
значения bool?
, Компилятор интерпретирует !null
как null
. Я ожидаю поднять
CS0266 (невозможно неявно преобразовать тип 'bool?' В 'bool')
Образец кода:
bool? nullableVal = null;
//if (nullableVal) //OK: CS0266 bool? can't be converted to bool
// ;
var expectCS0266 = !nullableVal;//No compiler error/warning
//if ((!null) ?? false)//OK: CS8310 Operator '!' cannot be applied to operands of type "<NULL>"
// ;
if (! nullableVal ?? false)
;//this statement isn't reached, because of precedence of ! is higher than ??
//and !null == null
if (!(nullableVal ?? false))
;//this statement is reached, OK
Может кто-нибудь доказать, почему компилятор прав или наоборот.
Всего 1 ответ
Смотрите Раздел 7.3.7 спецификации :
Поднятые операторы позволяют предопределенным и пользовательским операторам, которые работают с необнуляемыми типами значений, также использоваться с обнуляемыми формами этих типов. Поднятые операторы состоят из предопределенных и определенных пользователем операторов, которые отвечают определенным требованиям, как описано ниже:
- Для унарных операторов
+ ++ - -- ! ~
поднятая форма оператора существует, если оба типа операнда и результата являются типами значений, не допускающими значения NULL. Поднятая форма создается путем добавления одного?
модификатор операнда и тип результата. Поднятый оператор выдает нулевое значение, если операнд нулевой. В противном случае поднятый оператор разворачивает операнд, применяет базовый оператор и переносит результат.
(Акцент мой)
Так:
bool? x = null;
bool? y = !x;
Следует этому правилу Мы используем поднятую форму одинарного !
оператор, который приводит к null
если значение, к которому он применяется, равно null
.
!null
не разрешен, потому что null
не относится к типу Nullable<T>
. !(bool?)null
работает, однако (хотя он выдает предупреждение компилятора).
!
действительно имеет более высокий приоритет, чем ??
см. раздел 7.3.1