2011-08-15 77 views
13

我用我的C#代碼非常簡單三元表達式:奇怪的三元運算符行爲

helperClass.SomeData = helperClass.HasData ? GetSomeData() : GetSomeOtherData(); 

在這兩種情況下,表達式的每個路徑上的函數返回一個非空對象,但如果我看結果在調試器,它是零,直到我引用它的代碼,如使用斷言:

Debug.Assert(helperClass.SomeData != null); 

這纔會出現,如果我使用了「64」的情況發生或者「調試模式下的任何CPU「平臺設置。在「x86」模式下很好。

在假設我在編譯器或調試器中發現錯誤之前,我儘量保持謹慎,但我找不到任何其他解釋。

這裏有一個完整的類做一個攝製,只需調用SomeClass.SomeAction()在64位模式下的調試器和單步看到它:

public class SomeClass { 
    public bool HasData; 
    public object SomeData; 

    private SomeClass() { 
     HasData = false; 
    } 

    public static void SomeAction() { 
     var helperClass = new SomeClass(); 
     // Exhibits weird debugger behavior of having helperClass.SomeData = null after this line: 
     helperClass.SomeData = helperClass.HasData ? GetSomeData() : GetSomeOtherData(); 

     // Note that trying helperClass.SomeData.ToString() returns a debugger error saying SomeData is null 

     // But this code is just fine 
     //if(helperClass.HasData) { 
     // helperClass.SomeData = GetSomeData(); 
     //} 
     //else { 
     // helperClass.SomeData = GetSomeOtherData(); 
     //} 

     // In both cases though, after this line things are fine: 
     Debug.Assert(helperClass.SomeData != null); 
    } 

    private static object GetSomeData() { 
     return new object(); 
    } 

    private static object GetSomeOtherData() { 
     return new object(); 
    } 
} 

我缺少的東西,或這是一個錯誤在x64調試器中?我正在使用調試模式,因此不應該出現優化。

+2

請注意*調試符號生成*和*優化生成*實際上是正交的。雖然有點不尋常,但同時打開調試符號和優化是合法的。可能要仔細檢查你是不是在這種奇怪的配置。 –

+0

對於我的活動(Debug/x64)配置,未選中「Build」選項卡下的「Optimize code」複選框。我應該檢查別的地方嗎? –

+0

不是;聽起來像這不是問題。 –

回答

4

對我來說這似乎不是一個錯誤調試器,但可能是編譯器...

改變代碼

{ helperClass.SomeData = helperClass.HasData ? GetSomeData() : GetSomeOtherData(); } 

當IL產生的是不同的調試器工作原理預計...

+0

爲什麼你需要在它周圍放置{}? –

+0

我沒有說你必須...只是當反射器在拆解那條線時向我反饋了一些奇怪的代碼... – Yahia

+0

它看起來像一個錯誤(也許只是在編譯器中,因爲你建議)。即使ReSharper認爲我是一個傻子,我正在解決它的一個if語句:) –