2013-10-09 76 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。 –

相關問題