【问题标题】:Negation of null for Nullable<bool>Nullable<bool> 的 null 否定
【发布时间】:2020-02-12 14:27:03
【问题描述】:

在否定bool?null 值的情况下,我对c# 编译器感到困惑。编译器将!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

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

【问题讨论】:

  • this answer 有帮助吗? - “Nullable 是一种非常特殊的类型,它的神奇属性深深嵌入在 C# 语言和运行时”
  • @stuartd 来自 canton7 的答案似乎更短更清晰。

标签: c# compiler-errors logical-operators


【解决方案1】:

参见the spec 的第 7.3.7 节:

提升运算符允许对不可为空值类型进行操作的预定义和用户定义的运算符也可用于这些类型的可空形式。提升运算符由满足特定要求的预定义和用户定义的运算符构成,如下所述:

  • 对于一元运算符
    + ++ - -- ! ~
    如果操作数和结果类型都是不可为空的值类型,则存在运算符的提升形式。提升形式是通过将单个 ? 修饰符添加到操作数和结果类型来构造的。如果操作数为空,则提升的运算符产生空值。 否则,提升的运算符会解开操作数,应用底层运算符,然后包装结果。

(强调我的)

所以:

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

遵循此规则。我们使用一元 ! 运算符的提升形式,如果应用的值为 null,则结果为 null

!null 是不允许的,因为null 不是Nullable&lt;T&gt; 类型。但是,!(bool?)null 有效(尽管它会产生编译器警告)。

! 确实比?? 具有更高的优先级,请参阅第 7.3.1 节

【讨论】:

  • 我会标记它“如果操作数为空,则提升的运算符产生一个空值”粗体。感谢您从规范中引用!
猜你喜欢
  • 1970-01-01
  • 2012-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多