为什么短路不会阻止与逻辑AND(&&)的不可达分支相关的MissingMethodException?

时间:2011-03-08 13:31:12

标签: c# compact-framework short-circuiting

在检查我的Windows移动设备上是否有相机并启用时,我遇到了一些我不明白的事情。

代码如下所示:

    public static bool CameraP(){

        return Microsoft.WindowsMobile.Status.SystemState.CameraPresent;
    }

    public static bool CameraE()
    {
        return Microsoft.WindowsMobile.Status.SystemState.CameraEnabled;
    }

    public static bool CameraPresent1()
    {
        return Microsoft.WindowsMobile.Status.SystemState.CameraPresent
              && Microsoft.WindowsMobile.Status.SystemState.CameraEnabled;
    }

    public static bool CameraPresent2()
    {
        return CameraP() && CameraE();
    }

当我呼叫CameraPresent2()时,它返回false(没有相机存在)。但是当我调用CameraPresent1()时,我收到一条MissingMethodException并注释“找不到方法:get_CameraEnabled Microsoft.WindowsMo​​bile.Status.SystemState。”

第二个词是否在CameraPresent1中进行评估只是因为它们都是属性(语言级别)?

还有什么能解释行为上的差异吗?

4 个答案:

答案 0 :(得分:31)

第二个词没有评估。

第一个词没有评估。

CameraPresent1()方法甚至没有开始执行。

第一次调用CameraPresent1()时,运行时必须将MSIL JIT编译为本机代码。这需要解析所有方法调用,即使是只能有条件地访问的方法调用。编译因MissingMethodException而失败。

使用CameraPresent2(),只有在第一次调用CameraEnabled时才会调用对CameraE()的getter的调用,这种调用永远不会发生。

答案 1 :(得分:10)

C# Specification第7.12节

&&||运算符称为条件逻辑运算符。它们也被称为“短路”逻辑运算符。

&&||运算符是&运算符的条件版本。和|操作符:

  • 操作x && y对应于操作x & y,但仅当y不是x时才评估false

  • 操作x || y对应于操作x | y,但仅当y不是x时才评估true

<小时/> 也就是说,当且仅当 CameraE()为真时,C#规范才会保证CameraP()将被称为

这可能是积极的编译器优化的问题,因此实际的程序似乎违反了语言规范......

<小时/> 修改

是否可以设置断点并显示反汇编窗口,以查看生成的确切代码?

答案 2 :(得分:5)

只是一个疯狂的猜测,但这可能是JIT编译问题吗?当调用CameraPresent1时,它是否尝试将调用Microsoft.WindowsMo​​bile.Status.SystemState.CameraEnabled映射到底层设备?由于找不到方法get_CameraEnabled,整个函数失败并出现MissingMethodException。

答案 3 :(得分:0)

看着报道的问题,似乎毫无意义。这两个版本应该完全相同。我想知道,如果问题在于相机API在某个时刻使用dynamic,并且它正在尝试寻找true() / false() / &运营商。这可能会说服它切换到bool逻辑:

public static bool CameraPresent1()
{
    return ((bool)Microsoft.WindowsMobile.Status.SystemState.CameraPresent)
          && ((bool)Microsoft.WindowsMobile.Status.SystemState.CameraEnabled);
}