【问题标题】:Why && and || cannot be used for nullable type? [duplicate]为什么 && 和 ||不能用于可空类型? [复制]
【发布时间】:2011-05-22 22:51:26
【问题描述】:

可能重复:
AND operation cannot be applied between nullable bools.

我希望有类似的行为,例如 + 或 *。因此,如果任何操作数为 null,它应该返回 null,但如果在 && 或 || 中使用,编译会报错。为什么?

为了说明这一点:

//this compiles
int? x = null;
int? y = null;
var z = x*y;

// this doesn't compile
bool? x = null;
bool? y = null;
if(x && y)
    ....

【问题讨论】:

  • 你能提供一些失败的示例代码吗?我不确定我是否理解您所指的内容。
  • "如果任何操作数为 null,则应返回 null":&&|| 运算符属于 bool 类型,因此将始终返回布尔结果。当您获得可空类型时,只需使用 myNullable.HasValue && ...
  • 抱歉重复。我现在明白了为什么它在本质上不受支持,尽管在某些情况下它可能是有道理的。

标签: c# .net nullable


【解决方案1】:

如果要返回null,则布尔要求无效。

|| &&

基本上,它允许在if 语句中使用除bool 以外的值(特别是null),这将是未定义的行为,因为if 语句需要boolean 表达式。

有趣的是,这是 Java 和 C# 不同的领域之一。 Java 在if 语句中也需要布尔值,但它们允许bool?Nullable<bool>,或Java 中的Boolean)版本为null。这会导致在运行时出现一些意外的NullPointerExceptions,而 C# 通过此要求避免了这种情况。

【讨论】:

    【解决方案2】:

    可能是因为 && 和 ||是短路运算符。您可以使用 & 和 |与布尔?我相信你会得到三值逻辑 - null 被视为“未知”。所以 false & null 为 false,但 true & null 为 null。这足以令人困惑,可以跟踪,也不会造成短路!面对空值,短路实际上可能没有任何用处。

    编辑 - 考虑到,短路对于三值逻辑仍然有意义。左侧为 false 的逻辑 AND 将始终评估为 false,即使右侧为 null 也是如此。左侧为 true 的逻辑 OR 将始终评估为 true,即使右侧为 null 也是如此。我想这是那些“不值得努力实现”的功能之一。有时您需要短路布尔逻辑。有时您需要三值布尔逻辑。但两者很少重叠。

    【讨论】:

    • +1 不知道 ¦ 和 & 是为 bool 实现的吗?
    • 短路可为空的布尔值的问题是,如果你有 (null && M()),你会怎么做——你是否评估 M()?请记住,null 可能意味着“有一个真值,但我现在不知道它是什么”。 M() 可能有一个副作用,应该当且仅当左侧为真时进行评估,但我们不知道它是否为真。编译器不会要求你“我不知道”应该被视为“假”——如果事实证明它应该是真的怎么办?
    • 啊,谢谢。我认为这是不同心智模式的案例。在我的脑海中,我认为三值逻辑与具有两个输入和一个输出以及一个九项真值表,然后将短路视为过程:“从左到右评估输入表达式,直到输出明确” ,此时我只是将 null 视为另一个值——我还没有将它视为特殊的叠加。当您将“a && b”视为“评估 a,如果为 false,则返回 false,否则评估并返回 b”,它更有意义。
    【解决方案3】:

    即使 (x && y) 是可能的,结果也会是布尔值?而不是布尔值。 if () 仅适用于布尔值。

    尝试 if (((bool)(x ?? false)) && (bool)(y ?? false)) 代替。

    或者更好的是,按照 weebles 的回答:

    如果 (x & y == true)。

    【讨论】:

      【解决方案4】:

      可空类型实际上是对象。当您应用可空运算符“?”时对于一个值类型(例如 bool),它成为对一个对象的引用,该对象包含“null”或基础值类型的值。

      考虑一下:

      bool? isActive;
      

      这实际上变成了:

      Nullable<bool> isActive;
      

      值类型实际上变成了一个对象实例,因此不像常规值类型那样参与布尔表达式。

      更多信息:http://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx

      【讨论】:

      • 完全错误。 Nullable&lt;T&gt; 是一个结构体;不涉及拳击。
      • -1,您使用的术语令人困惑。 Nullable&lt;T&gt; 是一个结构,因此可空类型是 value 类型,因此您没有可空类型的 reference
      • 感谢投反对票的家伙,但 Nullable 实际上确实为非空类型设置了框。此外,Nullable 派生自 Object.
      • @jscharf:从 Object 派生并不意味着要装箱的类型。 struct、enum、任何ValueType,其实都是继承自Object
      • 嗯,技术上没有。他们在被装箱后做。非空 Nullable 的最终结果仍然作为对象在堆上结束,这就是为什么它没有隐式用于布尔表达式的原因,这是我的观点。
      猜你喜欢
      • 2014-08-07
      • 1970-01-01
      • 1970-01-01
      • 2020-04-06
      • 1970-01-01
      • 1970-01-01
      • 2014-01-26
      • 1970-01-01
      • 2018-12-09
      相关资源
      最近更新 更多