为什么“bool?”上没有解除短路操作符?

时间:2011-03-05 14:24:15

标签: c# operator-overloading short-circuiting lifted-operators

为什么bool?支持解除&&||?他们本可以取消truefalse运算符,这些运算符会间接添加&&||

运营商|&已经解除并实施了正确的Three-valued logic。但当然它们并不像||&&那样短路。

问题是他们在创建规范时决定不解除这些操作符的原因。所以“就像这样,因为规范说的如此”对“为什么?”没有答案。

解除truefalse时,null既不是true也不是false

public static bool operator true(bool? x) 
{
    return x.HasValue && x.Value
}

public static bool operator false(bool? x) 
{
  return x.HasValue && !x.Value
}

这会导致&&||的行为与非短路对应物一样。除了false && anythingtrue || anything短路(falsetrue在这两个示例中没有编译时常量。)

这与DBBool example on MSDN非常相似。

我认为解除这些操作员并不会引起任何意外或危险的行为。我错过了什么吗?

我已经阅读了another SO question,但没有找到满意的答案。


Jeff Yates的回答显示了为什么解除true / false运算符不是最优的一个很好的理由,它没有解释为什么直接解除&&||不好。由于运算符提升是编译器魔术,特殊情况Nullable<T>它不需要遵循正常类型的重载规则,因此能够提供&& / ||而无需提升{{1} }}

3 个答案:

答案 0 :(得分:4)

您建议为可空类型创建两种不同的使用模式。

请考虑以下代码:

bool? a = null;

// This doesn't currently compile but would with lifted true/false operators.
if (a)
{
}

// Whereas this provides a consistent use of nullable types.
if (a ?? false)
{
}

为了使用可空类型的一致性,不要解除true上的falsebool运算符是有意义的。我不知道这是不是为什么没有这样做的真正原因,但对我来说是有意义的。

答案 1 :(得分:4)

既然您已经证明提升truefalse在技术上是可行的,那么您的问题只有两个可能的答案(“他们”是编写编译器/规范的人):

  1. 这是规范中的错误,即。他们没有想到这一点。 (可能,但我怀疑)
  2. 他们认为解除短路操作员可能容易出错。它可能与推理相同,因为C#完全基于类(没有C ++中的唯一函数),或者为什么像if (myNullVar) { ... }这样的语句(myNullVar作为引用)在C#中不起作用(但在C / C ++中确实如此)。
  3. 我认为在使编程语言更强大并使其更不容易出错之间总是存在平衡。

    更新:为了您的兴趣,这就是official documentation所说的内容:

      

    这是不允许的,因为不清楚null在条件的上下文中意味着什么。

答案 2 :(得分:0)

false && anythingfalse相同。但是,如果您希望false && anything仅在anything为假时才为真,那么!anything就是您想要的。

此外,true || anythingtrue相同。 ......而且我不确定你怎么能在任何情况下让它返回假,因为没有任何意义让“这个或那个”什么都不返回!

...为什么在条件清晰简单的情况下为条件增加额外的重量呢?

我通常不熟练“因为它是如此”,但我没有看到添加此类功能的优势。