2012-10-28 221 views
2

我一直聽說C#使用懶惰評估。因此,對於某些代碼,if (true || DoExpensiveOperation()將返回true而不執行DoExpensiveOperation()懶惰評價不那麼懶惰?

在我看到以下問題接受記者採訪時測試,

static bool WriteIfTrue(bool argument) 
{ 
    if (argument) 
    { 
     Console.WriteLine("argument is true!"); 
    } 

    return argument; 
} 

static void Main() 
{ 
    // 1    0      0     1 
    WriteIfTrue((WriteIfTrue(false) & WriteIfTrue(true)) || WriteIfTrue(true)); 

    // 1    1      0      1 
    WriteIfTrue((WriteIfTrue(true) || WriteIfTrue(false)) & WriteIfTrue(true)); 

    // 0     0     0     0 
    WriteIfTrue((WriteIfTrue(false) & WriteIfTrue(true)) & WriteIfTrue(false)); 

    // 1    1      0     1 
    WriteIfTrue((WriteIfTrue(true) || WriteIfTrue(false)) & WriteIfTrue(true)); 
} 

多少次將其打印「的說法是真的!」到屏幕?

我會說7是正確的答案。現在,如果我堅持進入編譯器並運行它,它會打印它10次!懶惰評估全都出錯了?

+9

那些是&& &&操作員嗎? – Dialecticus

+5

這不是懶惰的評估,它是短路。此外,您正在將位運算符('&')與邏輯運算符('||')混合。 –

回答

34

我一直聽說C#使用懶惰評估。

這太過於模糊了,我不同意。如果你說C#中的||&&運算符是短路的,那麼只有在第一個操作數不能確定整個結果的情況下評估第二個操作數,我同意它。懶惰評估是一個更廣泛的概念 - 例如,LINQ查詢使用惰性(或延遲)評估,而不是實際獲取任何數據直到使用結果。

您使用的是& operator,這不是短路:

的&運算符計算,無論第一個的價值無論是運營商。

&& operator短路:

操作x && y對應於操作x & y不同之處在於,如果x是假的,y不計算,這是因爲與運算的結果爲假不管y的值是多少。

替換&&&無處不在您的代碼中,您會看到「參數是真實的!」打印8次(不是7 - 再次計算您的評論)。

+0

老實說現在不記得它是否是測試中的&& &&。當我測試它時,會解釋意想不到的行爲,謝謝! –