在C#中使用|(或)运算符

本文关键字:运算符 | 更新日期: 2023-09-27 18:11:39

我想知道这两种方法是否等效?其中一个比另一个好吗?

第一:

bool x = foo();
bool y = bar();
if(x || y)
{
   //...
}

第二:

if(foo() | bar())
{
   //...
}

在C#中使用|(或)运算符

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之前要评估xy,因此这与foo() | bar()相同。

现在,如果你比较

foo() | bar()

带有

foo() || bar()

那么他们就不一样了。但是,您之前对xy的评估足以使这两个测试等效。

|||之间的主要区别是短路,但这在这里无关紧要,因为使用||的代码已经预先评估了这两个表达式,所以短路在这里无关紧要。

假设foo()bar()都返回一个正常的bool,这应该是等价的。

如果返回类型与bool不同,则隐式转换和重载解析可能会导致不同的结果。

如果你使用的是底层值不同于01的黑布尔(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所需的全部功能。这可能好,也可能不好!