Nullable<bool> 的 null 否定

Negation of null for Nullable<bool>

在否定 bool?null 值的情况下,我对 c# 编译器感到困惑。编译器确实将 !null 解释为 null。我的期望是提高

CS0266 (Cannot implicitly convert type 'bool?' to '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

有人可以证明为什么编译器是正确的,反之亦然。

参见 the spec 的第 7.3.7 节:

Lifted operators permit predefined and user-defined operators that operate on non-nullable value types to also be used with nullable forms of those types. Lifted operators are constructed from predefined and user-defined operators that meet certain requirements, as described in the following:

  • For the unary operators
        + ++ - -- ! ~
    a lifted form of an operator exists if the operand and result types are both non-nullable value types. The lifted form is constructed by adding a single ? modifier to the operand and result types. The lifted operator produces a null value if the operand is null. Otherwise, the lifted operator unwraps the operand, applies the underlying operator, and wraps the result.

(强调我的)

所以:

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

遵守这条规则。我们正在使用一元 ! 运算符的提升形式,如果它应用的值是 null.

,则结果为 null

!null 是不允许的,因为 null 不是 Nullable<T> 类型。然而,!(bool?)null 有效(尽管它会产生编译器警告)。

! 确实比 ?? 有更高的优先级,见第 7.3.1 节