'&'与'&&'的使用区别

89

我看到了这个:

bool Isvalid = isValid & CheckSomething()

bool Isvalid = isValid && CheckSomething()

第二种情况可能是一个短路的场景。

那么我们不能总是只使用 & 而不是 && 吗?


4
如果不涉及位运算,不要使用 &,而应始终使用 &&。如果不确定,请使用 &&。 - Ilya Kogan
1
@Ilya:如果你不是在处理位,但第二个操作数因某种原因需要被评估呢? - LukeH
6
你的代码不易读懂。最好明确地调用你需要调用的内容,而不要在布尔逻辑表达式中使用隐含特性。有多少程序员会知道C#中这个隐藏特性,他们将来会维护你的系统。 - Ilya Kogan
4
@Ilya:我当然不会推荐使用&(或者通常情况下具有副作用的表达式); 我只是在展示这两个运算符之间的区别!(顺便说一句,&&&之间的区别并不是C#中的一个隐藏特性,它在我所知道的所有类C语言中都很常见。如果维护你的系统的人不知道这个区别,那么他们需要尽快接受一些培训。) - LukeH
是的,区别在于短路求值。但你搞反了:你几乎总是应该使用 &&。很难给出比这更好的答案。这两个运算符都是语言的特性,有其存在的理由。没有人可以告诉你忽略其中一个。 - Cody Gray
由于C#和CLI规范的差异,&&&对于布尔输入的输出不一定相同:https://dev59.com/MWAf5IYBdhLWcg3wZSFI - mallardz
4个回答

101

& 是按位 AND,意味着它在位级别上起作用。 && 是逻辑 AND,意味着它在布尔(true/false)级别上工作。逻辑 AND 使用短路(如果第一部分为 false,则没有必要检查第二部分)来防止运行多余的代码,而按位 AND 需要操作每个位来确定结果。

你应该使用逻辑 AND (&&) ,因为这是你想要的,而 & 可能会产生错误的结果。但是,如果您想评估其副作用,则需要单独运行第二种方法:

var check = CheckSomething();
bool IsValid = isValid && check;

28
当应用于布尔值时,这两种形式都是逻辑AND运算; 只是&&版本具有短路运算的特性。 - LukeH
6
如果您使用 &,则无论 isValid 的值如何,CheckSomething 都将始终被调用。如果您使用 &&,则仅在 isValid 为 true 时才会调用 CheckSomething。表达式本身的结果应该是相同的,无论您使用 & 还是 &&。(由您决定需要在什么情况下调用 CheckSomething。) - LukeH
4
这个答案正在meta上讨论。 - Script47
3
尽管“even though”和“actually”在使用布尔值作为操作数时可能是位运算符,但是这份文档并没有以这种方式讨论它:https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/boolean-logical-operators#logical-and-operator- - Mattias Nordqvist
3
这个答案在C#中不正确。其他语言使用&作为位运算符,但是在C#中,只有在应用于整数值时才将其用作位运算符,但对于布尔值,它将不起作用作为位运算符,而是作为逻辑AND运算符,评估两个操作数。请参见此链接adjan的答案应该被标记为正确答案。 - Hawkeye
显示剩余7条评论

57

C#有两种逻辑合取(AND)运算符适用于bool类型:

  1. x & y 逻辑 AND 运算符

    • 只有当xy都为true时,结果才为true
    • 同时对xy进行求值。
  2. x && y 条件逻辑 AND 运算符

    • 只有当xy都为true时,结果才为true
    • 首先对x进行求值,如果x求值为false,则立即返回false而不评估y短路计算)。

因此,如果您依赖于对xy的同时求值,可以使用&运算符,但它很少被使用并且很难阅读,因为副作用并不总是对读者清晰。

注意:对于整数类型intlong等),也存在二进制&运算符,它执行按位逻辑 AND 运算。


1
你能举个在C#中使用 & 运算符的实际例子吗? - eaglei22
@eaglei22 var bob = true; var bob2 = true; var bob3 = bob & bob2; 在许多CPU上,该示例中的&&&更快。 - mjwills
感谢您提供一个“逻辑”解释。 - Chris Catignani
2
这个回答真的需要标记为正确答案。Talljoe的回答对于C#的特性存在误解,会导致没有阅读所有评论和答案的读者得出错误的结论。 - Hawkeye
1
@Chris Catignani 如果您有一种方法可以进行评估,而且您仍然希望它运行。例如,如果(evalA() & evalB()),即使A为假,您可能希望B运行(也许是为了设置一个私有的布尔变量)。就我个人而言,如果需要的话,我会将其拆分。 - A_Arnold

16
在 && 中,只有在第一个表达式为真时才会评估第二个表达式。
而 & 只是一种确保两个表达式都被评估的方式,例如 true & true = true,true & false = false 等等。

6
“concatenate”不是那个意思。你的第二个句子有害。 - MarredCheese

8

1
好的,那么什么时候使用哪个? - V4Vendetta
& 可以与枚举值一起使用(当在枚举上使用 Flags 属性时)。欲了解更多信息,请搜索“枚举位和运算符”。 - Martijn
我想一般情况下只需使用&&,除非您始终希望评估CheckSomething。在这种情况下,请像Talljoe已经回答的那样操作。 - Pleun
链接(实际上)已经失效。它重定向到一些通用页面。 - Peter Mortensen
1
@PeterMortensen 我已经更新了链接(虽然是5年半后,但还是更新了) - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接