C# 将短路运算符与常规运算符组合是否会更改表达式的结果?

C# 将短路运算符与常规运算符组合是否会更改表达式的结果?,c#,boolean-logic,short-circuiting,C#,Boolean Logic,Short Circuiting,我一直认为使用条件布尔运算符(又称短路)代替常规布尔运算符不会影响表达式的结果 var result = true | false & false; 结果与 var result = true || false && false 这两个表达式都会导致true 但如果我混合使用正则运算符和条件运算符呢 var result1 = true || false & false; var result2 = true | false && false;

我一直认为使用条件布尔运算符(又称短路)代替常规布尔运算符不会影响表达式的结果

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
为false

至于原因,请参见:

&&和| |运算符后来因其“短路”行为而添加。丹尼斯·里奇(Dennis Ritchie)回顾时承认,当添加逻辑运算符时,按位运算符的优先级应该改变。但由于当时存在数百KB的C源代码,并且安装了三台计算机,丹尼斯认为C语言的变化太大了


&和|运算符计算两个参数(可能涉及调用一个方法),然后返回and-or操作的结果

&&和| |运算符仅对其参数进行求值,直到最终结果完全确定为止

例如:
true | SomeMethod()
false&SomeMethod()
调用SomeMethod()函数
true | | SomeMethod()
false&&SomeMethod()
不要


true
false
在本例中也可以是变量当然,我只是简单地使用常量使示例更容易理解。

所讨论的运算符的优先级似乎是直接从C(和C++)编程语言中的优先级复制而来的

现在在C语言中,他们对整数和布尔不使用不同的类型。例如,他们可以写:

if (i | j && x > 0)      // cf. the result2 of your question
这应该意味着“整数
i
j
按位or'ed给出非零的值,而数字
x
为正”。因此,当操作数被认为是整数(许多位数)时,应该主要使用
|
&
,当操作数被认为是布尔数时,应该主要使用
|
&

因此,在C语言中,
绑定比
&
更严格似乎是很自然的

在C#中,我们具有更高的类型安全性,并且没有从
Int32
Boolean
或从
Boolean
Int32
的转换。因此,不再可能“混合”事物,优先顺序也不再感觉自然

我想在理论上,在C#中,可以使运算符

public static bool operator |(bool b, bool c)
public static int operator |(int i, int j)
具有与运算符不同的优先级

public static bool operator |(bool b, bool c)
public static int operator |(int i, int j)
但这真的不会让事情变得更好吗


我认为很少有人在同一个表达式中使用布尔非短路运算符,如
|
和短路运算符,如
&&
,但当他们这样做时,他们应该非常小心优先级,或者只是在那里加上括号
()
(这也会使意图更加清楚).

短路肯定会改变副作用(即,如果布尔表达式是方法),因此进行区分是有意义的。@Antonijn:你的意思是它会改变副作用吗?对不起,我应该更清楚。答案很无聊,这是因为它继承了C语言的优先级和关联性规则,就像所有花括号语言一样。通过扮演语言设计师的角色使其有趣,并提出替代方案。您只有几个选择,优先级可以是相反的或相等的。如果等于,则结合性很重要,这可能是您忽略的。据我所知,&和|运算符用于按位运算,它们不是您在第一句“常规布尔运算符”中所能做到的。因为bool可以表示单个位,所以它也适用于它们。“& &和”算子是真值的逻辑运算符。毫无疑问,C++的设计者只是简单地复制了C和C++中已知的优先级。但请注意,您所指的线程主张将操作符
&
|
&&
|
移动到
==
的更远处=
运算符,使
&
|
先出现,然后出现
==
=,然后才是
&
|
。这在C语言中就不那么容易混淆了,因为它们对整数和布尔值使用相同的类型。因此,当他们说
if(i&j==0)
时,它可以很好地编译(不会用C#with
int
编译),但肯定不同于预期的
if((i&j)==0)
。我认为只有在需要按位和/或时才使用
&
。从现在起,对于布尔和/或,我将始终使用
&&
|