为什么C#&&和||运营商的工作方式如何?

时间:2011-03-05 11:23:44

标签: c#

这是一个tl; dr

我来自C ++背景。 &安培;&安培;假设检查左侧是否为真,右侧是否为真。是什么&与此有什么关系?为什么它被用于&&逻辑?


我无法理解http://msdn.microsoft.com/en-us/library/aa691312%28v=vs.71%29.aspx并提出问题。我花了很长时间才理解并接受这个答案。我不得不做很多跟进阅读How does operator overloading of true and false work?

  

操作x&& y被评估为   T.false(x)? x:T。&(x,y)

为什么它这样做呢?如果false重载返回true并且true运算符返回true,则根本不计算y。 WTF !!!!

我仍然无法理解。因为这对我来说太奇怪了,我花了一些时间来理解另一个问题的答案。在C#中v = 1 && 2;无法正常工作,你不能做&&在英特尔。在C中,这返回true(继承人代码/示例http://codepad.org/9iCaqzQ2)。如果我们遵循上面的操作规则,我们会这样做

(使用1&& 2)

  • Int.False(1)为false
  • 1& 2(== 0)
  • Int.True(0)(== false)

这会让你得到错误的结果。

那么...... C#做&&&&& (和||)运算符的方式。

7 个答案:

答案 0 :(得分:8)

&安培;&安培;是定义作为短路运算符;如果第一个操作数评估为假,则 需要 在那里短路而不评估右侧。您还希望它还能做什么?这允许像if(arg != null && arg.Foo) {...}

这样的检查

你的问题基本上是“如果我写了一个错误的操作错误的实现,那就会发生错误的事情”......所以;不要那样做!或者不写一个真/假运算符,或者如果你这样做;做对了......

还有&| 短路。

答案 1 :(得分:3)

C#比C ++更安全。

首先&重载,有两个版本,一个是按位AND,它对两个整数类型(如int,long)进行操作,并从第一个参数返回AND的结果,并在第二个参数中返回corresponging位。例如0011& 1010 == 0010。

第二个重载是逻辑AND,它对两个布尔类型(bool)进行操作,当且仅当两个参数都为真时才返回true。

最后你有&&这是有条件的AND,它再次运行两个布尔类型并返回true,当且仅当两个参数都为真但它还有添加的保证,如果第一个参数为真,则不会计算第二个参数。这允许你编写像if(arr!= null&& arr.Length> 0)这样的东西......没有短路行为,这会给你一个空引用异常。

|的规则和||是相似的,|按位和逻辑OR重载,||是有条件的OR。

你可能与C ++行为混淆的原因是整数类型可以隐式转换为C ++中的bools,0是假的,其他任何都是真的,所以5&& 5在C ++中返回true。在C#中,intergral类型不能隐式转换为bools,因此5&& 5是类型错误。 &安培;&安培;和||然而,在C ++中也是短路的,所以你不应该对C#中的相同内容感到惊讶。

答案 2 :(得分:3)

据我了解,您希望将a && b定义为((bool)a)&&((bool)b)而不是C#使用的内容。

但我认为引入了这种运算符重载来支持三态bool,例如bool?DBBool

让我们为这种类型定义几个例子:

没有短路:

null && true == null
null && false == false
null || true == true
null || false == null

可能发生短路:

false && null == false
true || null == true

这里的基本思想是将null视为未知值,如果结果未确定则返回null,如果结果不改变则返回bool,无论你将什么放入null参数。

现在,您要在此类型上定义短路逻辑andor。如果您使用C#truefalse运算符执行此操作,这两个运算符都会在false参数上返回null,您将获得所需的行为。有了类似的行为,你就没有。

C#设计人员可能并不关心整数中的逻辑and / or。整数不是布尔值,因此不应提供逻辑运算符。那个bool和整数是同一个东西是c的历史属性之一,新语言不需要镜像。由于c无法区分布尔值和整数,int上的按位与逻辑运算符的区别仅存在于c中。在区分这些类型的语言中,这种区别是不必要的。

在C#中调用&按位操作会产生误导。 && vs &的本质不是逻辑与按位and。这不是由您使用的运算符决定的,而是由您使用的类型决定的。在逻辑类型(boolbool?DBBool)上,两个运算符都是逻辑的,而在整数类型&上是按位的,而&&没有意义,因为你不能在整数上短路。 && vs &的本质是第一次短路而第二次没有。

对于完全定义运算符的情况,与c解释一致。并且由于&&没有在整数上定义,因为对于&&的C#解释没有意义,因此不存在关于如何对整数求值&&的问题。

答案 3 :(得分:0)

如果将它们转换为VB.Net,这些运算符将变得更容易理解,如下所示:

&安培;&安培; = AndAlso:IF foo IsNot Nothing AndAlso foo.bar = 1 then<> ...

|| = OrElse:如果foo是Nothing OrElse foo.bar = 0那么......<> ...

当你用英语阅读时,你真的知道他们想要实现的目标。

答案 4 :(得分:0)

这里可能忽略的一个问题是为什么C#不会自动将整数转换为布尔值?

自动将int添加到bool(使用C / C ++规则)允许意外分配而不是比较两个值。 C#语言设计师可能想避免这种情况......

int a, b;
if(a == b)
    { /* They are equal, so execute this code... */ }

if(a = b)
    { /* Were they actually equal? Dunno, but they are now... */ }

while(a = b)
    { /* Eternal loop */ }

答案 5 :(得分:-1)

如果您想要评估双方,您需要使用'标准'和&和|运营商。通常你想要&&和||运营商虽然效率

答案 6 :(得分:-2)

如果x == false,则x && y始终为false - >无需查看y的值。如果x == true,则x & y发生。这为您提供了优化的逻辑运算。

对于int,它将类似于:T.false(x == true) ? x : T.&(x == true, y == true)