2011-08-15 76 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语句:) –