2011-03-05 89 views
18

爲什麼bool?支持解除&&||?他們可能已經取消了truefalse運營商,這些運營商可能間接增加了&&||爲什麼在`bool?'上沒有解除短路操作?

運營商|&已被解除並執行正確的Three-valued logic。但當然它們不是像||&&那樣短路。

問題是爲什麼他們在創建規範時決定不提升這些操作員。所以「這是這樣的,因爲規格說明是這樣的」對於「爲什麼?」沒有答案。

當擡起truefalse,使null既不是true也不false

public static bool operator true(bool? x) 
{ 
    return x.HasValue && x.Value 
} 

public static bool operator false(bool? x) 
{ 
    return x.HasValue && !x.Value 
} 

這將導致&&||行爲就像他們的非短路同行。除了false && anythingtrue || anything會短路(falsetrue在這兩個示例中沒有編譯時間常量)。

這與DBBool example on MSDN非常相似。

我沒有看到通過提升這些操作員而引入的令人驚訝或危險的行爲。我錯過了什麼?

我已閱讀another SO question對此,但發現沒有滿意的答案。


傑夫·耶茨的回答顯示了一個很好的理由,爲什麼提起true/false運營商是不是最佳的,它並不能解釋爲什麼直接提升&&||是壞的。由於操作員提升是特殊情況下的編譯器魔術,因此不需要遵循正常類型的超載規則,因此無需提升即可提供&&/||true

+3

這不會假設NULL意味着錯誤嗎?不是每個人都會同意這一點。在例如關係理論(和SQL)NULL和TRUE,NULL和NULL,FALSE或NULL是NULL,它既不是真也不是假 – nos 2011-03-05 14:29:40

+0

應用於null的運算符'false'返回false。這導致'&&'不會短路並返回null和任何東西。 – CodesInChaos 2011-03-05 14:33:37

+0

http://en.wikipedia.org/wiki/Three-valued_logic – Jan 2011-03-05 14:34:02

回答

0

false && anythingfalse相同。但是,如果您希望false && anything僅在anything爲假時才爲true,那麼!anything就是您想要的。另外,true || anythingtrue相同。 ......我不確定你會如何在任何情況下都會返回錯誤,因爲如果「這個或那個」沒有任何回報,這是沒有意義的!

...爲什麼在條件完全清晰和簡單時增加額外的重量?

我通常不擅長「因爲這是如此」,但我沒有看到添加這種功能的優勢。

+0

在這個例子中,我不是指'false'是一個編譯時常量。但是一個已經被評估爲假的表達,從而使得對右側的評估變得不必要。 – CodesInChaos 2011-03-05 14:31:41

+0

錯誤&&任何內容都是錯誤的。沒有? – Andrey 2011-03-05 14:33:59

+1

哦!所以,即使'cond1'爲false,你也要評估'cond1 && cond2'而你想要評估'cond2'? – 2011-03-05 14:35:48

4

你建議爲可空類型創建兩種不同的使用模式。

考慮下面的代碼:

bool? a = null; 

// This doesn't currently compile but would with lifted true/false operators. 
if (a) 
{ 
} 

// Whereas this provides a consistent use of nullable types. 
if (a ?? false) 
{ 
} 

對於可空類型的使用一致性,是有意義的不是解除truefalse運營商對bool。我不知道這是否是未完成的真正原因,但這對我來說很有意義。

+0

我不知道'if'使用'true'運算符。我認爲它需要隱式轉換爲'bool'。但我只是測試它,你是對的。這仍然不能解釋爲什麼他們不會解除&&和||直接不用解除'true'或'false'。 – CodesInChaos 2011-03-05 18:38:19

+1

@CodeInChaos:你怎麼樣? &&和||要求在任一側布爾(見規格) - 不解除「真」或「假」,這是不能做到的。 – 2011-03-07 02:47:41

4

既然你表明提升truefalse在技術上是可行的,只有兩個你的問題可能的答案(用「他們」是誰寫的編譯器/規格的人):

  1. 這是一個錯誤在規範中,即。他們沒有想到這一點。 (可能,但我懷疑它)
  2. 他們認爲解除短路操作可能容易出錯。它可能與C#爲完全基於類的原因(C++中沒有唯一函數)或者爲什麼像if (myNullVar) { ... }(以myNullVar作爲參考)這樣的語句在C#中不起作用(但它在C/C++中有效) )。

我認爲在使編程語言更加強大並使其不太容易出錯的問題上保持平衡。

更新:只爲你的興趣,這是什麼official documentation說:

這是不允許的,因爲目前還不清楚是指在有條件的情況下什麼空。

+2

這個答案很好地說明了爲什麼在給定條件實現的方式(IMO在條件中使用op_true是愚蠢的,我需要隱式轉換爲bool)時解除op_true/op_false是一個糟糕的主意,它並不能說明爲什麼短路操作員不應直接解除。 – CodesInChaos 2011-09-07 12:46:15

+1

@CodesInChaos:當C#做出(恕我直言)不幸的決定,隱式提升可空類型的所有運算符時,如果任一操作數爲null,則結果應爲'null',這意味着'true | null「和」false&null「分別不能評估爲」true「和」false「,這與三值邏輯的情況相同,而是必須評估爲」null「才能與其他提升的操作員保持一致。 '&&'和'||'的正常含義是,如果給定相同的操作數,它們應該返回與'&'和'|'相同的值,但是隻能評估正確的操作數... – supercat 2014-06-02 19:35:59

+1

...價值可能會影響結果。雖然通過評估左手邊操作數非空時的右手邊可以使'&&'和'||'符合'&'和'|'的要求,假如'bool b = false;布爾? bq = false;',表達式'bq && f()'評估右邊,儘管'b&f()'不會。 – supercat 2014-06-02 19:43:28

相關問題