2013-10-09 55 views
0

我今天碰到了一些代码,它检查了一些错误条件。一直使用一个布尔值,但不是每次用=重新分配它,而是重新分配&=,导致布尔值和新值的先前值的位逻辑与。代码看起来像这样:是否有理由在布尔值上使用&=而不是= =?

bool result = FirstCheck(); 
Assert(result); 
result &= SecondCheck(); 
Assert(result); 
... 

现在我很好奇为什么有人会这样做?这是逻辑上等同于刚刚重新分配布尔值如由下面的可能的分支:

  1. FirstCheck失败(返回false)和断言程序失败,并且永远不会使得它SecondCheck
  2. FirstCheck传递(返回真正的),程序使它成为SecondCheck。如果SecondCheck返回true,则结果为true,因为true & true = true。如果SecondCheck返回false,则结果为false,因为true & false = false。

由于没有逻辑差异,是否还有其他一些原因&=可能更可取?还是更可能是一些旧代码的遗留物,它们从来没有改变过?

编辑: 为了澄清,Assert始终是活动代码。我在调查一个错误时偶然发现了这段代码,因为断言失败了。

回答

1

我想,在开始的时候是:

bool result = FirstCheck(); 
result &= SecondCheck(); 
Assert(result); 

所以代码是检查结果均为阳性,但之后有人在firstCheck()之后添加了Assert()。

或者该人可能来自C++背景,并认为按位运算符比逻辑运算符更快。

+0

是否在某些位运算符比逻辑一快的情况下? – GBleaney

+0

这*不*执行按位与。当在C#中调用布尔值时,'&'操作符只会执行非短路AND操作。所以它永远不会更快,它可能会更慢。只有在不考虑result的值的情况下执行'SecondCheck'的副作用是非常重要的。要么,要么只是一个错误。 – Servy

1

您假定断言已启用。如果这是使用Debug.Assert,则只有在定义了DEBUG条件编译符号时才会实际调用该方法。

假设result稍后使用(超出断言),那么当FirstCheck()返回false时会有差异。

0

像其他人说的那样,Assert可能并不总是活动代码。那么让我们假设第一个和第三个检查返回true,第二个检查返回false。因此,如果您有

x = FirstCheck() 
x = SecondCheck() 
x = ThirdCheck() 

那么x将等于true。

但是,如果你没有

x &= FirstCheck() 
x &= SecondCheck() 
x &= ThirdCheck() 

X就等于假

2

是的,原因是你使用单一的布尔累积多个函数的返回码。

没有& =你在每次调用时用最新函数覆盖返回码,因此你只能测试最后一个函数是否成功。与& =如果一个函数返回false,那么返回代码从该点开始保持为假,所以你知道至少有一个函数失败。

它还保存这样

bFirstCheck == fn1(); 
bSecondCheck == fn2(); 
bThirdCheck == fn3(); 

if (bFirstCheck && bSecondCheck && bThirdCheck) { 
} 

编写代码时,你可以写类似的代码:

bCheck = fn1(); 
bCheck &= fn2(); 
bCheck &= fn3(); 

if (true == bCheck) { 
} 
+2

没有理由将布尔值与“true”进行比较。这是一个noop。只要写'if(bCheck)'。 – Servy

+0

但是,感谢您的好评,这并不能真正回答我的具体问题,因为分配之间的断言否定了您在示例中提到的任何好处 – GBleaney

+0

Assert()仅适用于调试构建,在此用作方便提醒您哪些功能失败,它将在发布版本中编译为NO-OP。 –

相关问题