Отрицание нуля для Nullable <bool> - PullRequest
0 голосов
/ 12 февраля 2020

Я путаюсь с компилятором 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 Ответ

4 голосов
/ 12 февраля 2020

См. Раздел 7.3.7 из спецификация c:

Поднятые операторы разрешают предопределенные и определяемые пользователем операторы, которые работают с необнуляемыми типами значений, которые также могут использоваться с обнуляемыми формами этих типов Поднятые операторы состоят из предопределенных и определенных пользователем операторов, которые отвечают определенным требованиям, как описано ниже:

  • Для унарных операторов
    + ++ - -- ! ~
    поднятая форма оператора существует, если оба типа операнда и результата являются типами значений, отличными от NULL. Поднятая форма создается путем добавления одного модификатора ? к операнду и типу результата. Поднятый оператор выдает нулевое значение, если операнд нулевой. В противном случае поднятый оператор разворачивает операнд, применяет нижележащий оператор и упаковывает результат.

(выделение)

Итак:

bool? x = null;
bool? y = !x;

Следует этому правилу. Мы используем поднятую форму унарного оператора !, что приводит к null, если значение, к которому он применяется, равно null.

!null не допускается, потому что null не относится к типу Nullable<T>. Однако !(bool?)null работает (хотя и выдает предупреждение компилятора).

! действительно имеет более высокий приоритет, чем ??, см. Раздел 7.3.1

...