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

在检查我的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评估第二个术语是因为它们都是属性(在语言级别)?

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

第二个术语未经评估。

第一个术语未经评估。

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

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

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

C#规范部分7.12

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

&&|| 运算符是&和|的条件版本 运营商:

  • 操作x && y对应于操作x & y ,除了仅当x不为false时才计算y

  • 操作x || y x || y对应于操作x | y x | y ,除了仅在x不为true时才计算y


也就是说C#规范保证当且仅当 CameraP()为真时才会调用CameraP()

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


编辑:

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

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

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

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