在C#中使用|(或)运算符
本文关键字:运算符 | 更新日期: 2023-09-27 18:11:39
我想知道这两种方法是否等效?其中一个比另一个好吗?
第一:
bool x = foo();
bool y = bar();
if(x || y)
{
//...
}
第二:
if(foo() | bar())
{
//...
}
http://msdn.microsoft.com/en-us/library/6373h346(v=vs.71(.aspx
条件OR运算符(||(对其布尔操作数执行逻辑OR,但仅在必要时计算第二个操作数。
http://msdn.microsoft.com/en-us/library/kxszd0kx(v=vs.71(.aspx
二进制|运算符是为整型和布尔预定义的。对于整型,|计算其操作数的位"或"。对于布尔操作数,|计算其操作数的逻辑或;也就是说,当且仅当其两个操作数都为false时,结果为false。
这两个版本是等效的。||
操作员短路,但|
不短路。由于在测试x || y
之前要评估x
和y
,因此这与foo() | bar()
相同。
现在,如果你比较
foo() | bar()
带有
foo() || bar()
那么他们就不一样了。但是,您之前对x
和y
的评估足以使这两个测试等效。
|
和||
之间的主要区别是短路,但这在这里无关紧要,因为使用||
的代码已经预先评估了这两个表达式,所以短路在这里无关紧要。
假设foo()
和bar()
都返回一个正常的bool,这应该是等价的。
如果返回类型与bool
不同,则隐式转换和重载解析可能会导致不同的结果。
如果你使用的是底层值不同于0
或1
的黑布尔(AFAIK只能通过不安全的代码实现(,它们也可能不同。
对于被黑的布尔,我们可以观察到|
具有二进制语义,甚至在布尔上也是如此。我不确定这是在运行时级别指定的行为,还是只是未定义的行为,因此可能会随着不同的编译器/抖动版本而改变。我使用显式结构布局的实现当然是未定义的行为,但我不确定其他语言是否可以在没有这种破解的情况下创建这样的bool。
void Main()
{
bool b1 = hackbool(1);
bool b2 = hackbool(2);
((b1 | b2)&b2).Dump();
((b1 || b2)&b2).Dump();
}
[StructLayout(LayoutKind.Explicit)]
internal struct Evil
{
[FieldOffset(0)]public int i;
[FieldOffset(0)]public bool b;
}
bool hackbool(int i)
{
Evil e=new Evil();
e.i=i;
return e.b;
}
if(foo() | bar())
{
//...
}
若你们指的是foo() || bar()
,那个么,在某种情况下,这将比第一个版本更快。当foo()
为真时,它不会执行bar()
,但在|的情况下,它等效于
||
是条件OR(测试布尔值(,|
是位OR。
|是一个artihmetic运算符。所以(二进制(0101|0111=0111(在任意一个操作数都有1.的情况下输入一
||是一个逻辑运算符,如果(a||b({do something}发生在a或b为true的情况下。
他们完全不同。
||也是一个"序列点"例如,如果你对进行编码
if (foo() || bar())
....
如果foo((返回true,则bar((甚至可能不会被调用,因为"If"具有将表达式求值为true所需的全部功能。这可能好,也可能不好!