将短路运算符与常规运算符组合是否会更改表达式的结果
本文关键字:运算符 表达式 结果 是否 短路 常规 组合 | 更新日期: 2023-09-27 17:57:07
认为使用条件布尔运算符(又名短路)代替常规布尔运算符不会影响表达式的结果。
var result = true | false & false;
具有与
var result = true || false && false
这两个表达式都会导致true
。
但是,如果我混合使用常规运算符和条件运算符呢?
var result1 = true || false & false;
var result2 = true | false && false;
你会期待什么?我希望这些仍然会返回true
.但事实并非如此。结果 2 将被false
!
我知道这是因为运算符优先级。优先顺序为 & | && ||
。这对我来说似乎违反直觉。我希望一个 & && | ||
的顺序,在这种情况下,所有结果都是一样的(我认为)。
所以我想我真正的问题不是短路是否会改变结果。问题是为什么优先顺序如此之大,短路可以改变结果。
var result2 = true | false && false;
计算公式为:
var result2 = (true | false) && false;
因为|
先于&&
.现在(true | false)
计算结果为 true
,true && false
为假。
至于为什么,请看这个问题:
&&&和||运算符是后来添加的,因为它们的"短路"行为。Dennis Ritchie回想起来承认,在添加逻辑运算符时,应该改变按位运算符的优先级。但是,当时有几百千字节的C源代码,并且安装了三台计算机,Dennis认为C语言的变化太大了。
有问题的运算符的优先级似乎是直接从 C(和 C++)编程语言中的优先级复制而来的。
现在在 C 中,他们不对整数和布尔值使用不同的类型。例如,他们可以写:
if (i | j && x > 0) // cf. the result2 of your question
这应该意味着"整数i
和j
按位或给出非零的东西,并且x
的数字是正数"。因此,当操作数被认为是整数(多位数字)时,应该主要使用|
和&
,而当操作数被认为是布尔值时,应该主要使用||
和&&
。
因此,在 C 语言中,|
比 &&
绑定更严格似乎是很自然的。
在 C# 中,我们具有更高程度的类型安全性,并且没有从 Int32
到 Boolean
或从 Boolean
到 Int32
的转换。因此,不再可能"混合"事物,并且优先级不再自然。
我想在 C# 的理论上,可以使运算符
public static bool operator |(bool b, bool c)
具有与运算符不同的优先级
public static int operator |(int i, int j)
但这真的不会让事情变得更好吗?
我认为人们很少在同一表达式中使用布尔非短路运算符(如|
)和短路运算符(如&&
),但是当他们这样做时,他们应该非常小心优先级,或者只是将括号()
放在那里(这也会使意图更加清晰)。
| 运算符计算这两个参数(可能涉及调用方法),然后返回 and- 或 or 操作的结果。
&&&和||运算符只评估他们的参数,直到最终结果完全确定。
例如: true | SomeMethod()
和 false & SomeMethod()
调用 SomeMethod() 函数 true || SomeMethod()
和 false && SomeMethod()
没有。
当然,这个例子中的true
和false
也可以是变量,我只是使用常量使示例更易于理解。