Отрицание нуля для Nullable <bool>

Я запутался с компилятором 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


Есть идеи?

10000