当前位置:  开发笔记 > 编程语言 > 正文

一个明确的,外行的解释|之间的区别 和|| 在c#?

如何解决《一个明确的,外行的解释|之间的区别和||在c#?》经验,为你挑选了5个好方法。

好的,所以我已多次阅读过这篇文章,但我还没有听到一种清晰,易懂(且令人难忘)的方法来了解它们之间的区别:

if (x | y)

if (x || y)

..在C#的背景下.任何人都可以帮助我学习这个基本事实,以及C#如何具体地对待它们(因为它们似乎做同样的事情).如果给定代码片段之间的差异是无关紧要的,我应该将其默认为最佳实践?



1> John Feminel..:

||逻辑或运算符.看到这里.它评估true至少一个操作数是否为真.您只能将它与布尔操作数一起使用; 将它与整数操作数一起使用是错误的.

// Example
var one = true || bar();   // result is true; bar() is never called
var two = true | bar();    // result is true; bar() is always called

|运营商.看到这里.如果应用于布尔类型,则计算true至少一个操作数是否为真.如果应用于整数类型,则计算为另一个数字.如果至少一个操作数具有相应的位集,则该数字的每个位设置为1.

// Example
var a = 0x10;
var b = 0x01;
var c = a | b;     // 0x11 == 17
var d = a || b;    // Compile error; can't apply || to integers
var e = 0x11 == c; // True

对于布尔操作数,a || b相同a | b,条件是唯一的例外b,如果不评估a为真.因此,||据说是"短路".

如果给定代码片段之间的差异是无关紧要的,我应该将其默认为最佳实践?

如上所述,差异并非无关紧要,因此这个问题部分没有实际意义.至于"最佳实践",没有一个:您只需使用正确的操作符即可.在一般情况下,人们倾向于|||布尔操作数,因为你可以肯定它不会产生不必要的副作用.



2> Guffa..:

当与布尔操作数一起使用时,运算|符就像逻辑运算符一样||,但区别在于||运算符执行短路评估而|运算符不执行.

这意味着始终使用|运算符计算第二个操作数,但使用||运算符时,仅在第一个操作数计算为false时才计算第二个操作数.

对于两个操作符,表达式的结果总是相同的,但如果第二个操作数的求值导致其他内容发生变化,那么只有在使用|运算符时才会发生这种情况.

例:

int a = 0;
int b = 0;

bool x = (a == 0 || ++b != 0);

// here b is still 0, as the "++b != 0" operand was not evaluated

bool y = (a == 0 | ++b != 0);

// here b is 1, as the "++b != 0" operand was evaluated.

||运算符的短路评估可用于编写较短的代码,因为仅在第一个操作数为真时才评估第二个操作数.而不是像这样写:

if (str == null) {
   Console.WriteLine("String has to be at least three characters.");
} else {
   if (str.Length < 3) {
      Console.WriteLine("String has to be at least three characters.");
   } else{
      Console.WriteLine(str);
   }
}

你可以像这样写:

if (str == null || str.Length < 3) {
   Console.WriteLine("String has to be at least three characters.");
} else{
   Console.WriteLine(str);
}

仅当第一个操作数为false时才计算第二个操作数,因此您知道可以安全地在第二个操作数中使用字符串引用,因为如果计算第二个操作数,它不能为空.

在大多数情况下,您可能希望使用||运算符而不是|运算符.如果第一个操作数为false,则无需计算第二个操作数以获得结果.此外,很多人(显然)不知道你可以使用|带有布尔操作数的运算符,因此当他们在代码中使用这种方式时,他们会感到困惑.


希望我能给+10,这是与C#有关的最相关的答案.虽然所有其他技术上都是正确的,但他们忽略了这个问题与C#中的布尔逻辑有关的事实.

3> Cheeso..:

他们不一样.一个是按位OR,一个是逻辑OR.

X || Y,是逻辑的,或者与"X或Y"相同,适用于bool值.它用于条件或测试.在这种情况下,X和Y可以替换为任何计算为bool的表达式.例:

if (File.Exists("List.txt")  ||  x > y )  { ..}

如果两个条件中的任何一个为真,则子句的计算结果为true.如果第一个条件为真(如果文件存在),则第二个条件不需要也不会被评估.

单个管道(|)是按位OR.要知道这意味着什么,您必须了解数字如何存储在计算机中.假设您有一个保持值为15的16位数量(Int16).它实际上存储为0x000F(十六进制),与二进制的0000 0000 0000 1111相同.按位OR取两个量并将每对相应位的OR组合在一起,因此如果该位在任一数量中为1,则结果为1.因此,如果a = 0101 0101 0101 0101(以十六进制计算为0x5555)和b = 1010 1010 1010 1010(即0xAAAA),则a | b = 1111 1111 1111 1111 = 0xFFFF.

您可以在C#中使用按位OR(单个管道)来测试是否打开了一个或多个特定位组.如果你有12个布尔值或二进制值来测试,你可能会这样做,而且它们都是独立的.假设您有一个学生数据库.一组独立的布尔可能是类似的东西,例如男/女,家庭/校园,当前/非当前,已登记/未登记等.而不是为每个值存储一个布尔字段,您可以存储每一个只有一个位.男性/女性可能是第1位.注册/不可能是第2位.

然后你可以使用

 if ((bitfield | 0x0001) == 0x0001) { ... }

作为测试,看看是否没有打开位,除了"student is male"位,这被忽略.咦?好吧,按位OR为每个数字中的每个位返回1.如果按位或以上的结果= 0×0001,这意味着有没有位位域开启,除了可能在第一位(0×0001),但你不能肯定地告诉第一位是开的,因为它它蒙面了.

有一个对应的&&和&,它是逻辑AND和按位AND.他们有类似的行为.

您可以使用

 if ((bitfield &  0x0001) == 0x0001) { ... }

查看位域中是否打开了第一位.

编辑:我不敢相信我为此投了票!



4> Tony the Pon..:

很好的答案,但让我补充说,||如果左侧表达式是,则不评估右侧表达式true.如果评估术语是a)表现密集型或b)产生副作用(罕见),请记住这一点.



5> jalf..:

与迄今为止的大多数答案不同,其含义与C++中的含义并不完全相同.

对于评估为布尔值的任何两个表达式A和B,A || B和A | B几乎做同样的事情.

A | 乙评估两个 A和B,如果他们中的一个计算结果为真,结果为真.

A || B几乎完全相同,除了它首先评估A,然后只在必要时评估B. 如果A或B为真,则整个表达式为真,如果A为真,则不需要对B进行全部测试.所以|| 短路,并在可能的情况下跳过评估第二个操作数,其中| 运营商将始终评估两者.

| 操作员不经常使用,而且通常不会有所作为.我能想到的唯一一个常见的例子就是:

if ( foo != null || foo.DoStuff()){ // assuming DoStuff() returns a bool

}

这是有效的,因为如果左侧测试失败,则永远不会调用DoStuff()成员函数.也就是说,如果foo为null,我们就不会在其上调用DoStuff.(这会给我们一个NullReferenceException).

如果我们使用了| 运算符,无论foo是否为null,都会调用DoStuff().

在整数上,只有| 运算符是定义的,并且是按位OR,正如其他答案所描述的那样.|| 虽然operator不是为整数类型定义的,但是很难让它们在C#中混淆.

推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有