c# compact-framework short-circuiting

c# - ¿Por qué el cortocircuito no evita la excepción MissingMethodException relacionada con la rama inalcanzable de lógica AND(&&)?



compact-framework short-circuiting (4)

Al realizar una verificación, si hay una cámara presente y habilitada en mi unidad móvil con Windows, encontré algo que no entiendo.

El código se ve así:

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(); }

Cuando llamo a CameraPresent2() , devuelve false (no hay cámara presente). Pero cuando llamo a CameraPresent1() una MissingMethodException con el comentario "No se pudo encontrar el método: get_CameraEnabled Microsoft.WindowsMobile.Status.SystemState".

¿Se evalúa el segundo término en CameraPresent1 solo porque ambos son propiedad (a nivel de idioma)?

¿Hay algo más que explique la diferencia de comportamiento?


Especificación C # sección 7.12

El && y || Los operadores se denominan operadores lógicos condicionales. También se les llama operadores lógicos de "cortocircuito".

El && y || Los operadores son versiones condicionales del & y | operadores:

  • La operación x && y corresponde a la operación x & y , excepto que y se evalúa solo si x no es false .

  • La operación x || y x || y corresponde a la operación x | y x | y , excepto que y se evalúa solo si x no es true .

Es decir, la especificación de C # garantiza que se CameraE() si y solo si CameraP() es verdadero.

Esto puede ser un problema con las optimizaciones agresivas del compilador, y por lo tanto el programa actual parece violar las especificaciones de idioma ...

Editar:

¿Es posible colocar un punto de interrupción y mostrar la ventana de desensamblaje para ver el código exacto generado?


El segundo término no es evaluado.

El primer término no se evalúa.

El método CameraPresent1() ni siquiera comienza a ejecutarse.

Cuando llama a CameraPresent1() por primera vez, el tiempo de ejecución debe JIT-compilar el MSIL en el código nativo. Esto requiere resolver todas las llamadas de métodos, incluso aquellas que podrían alcanzarse de manera condicional. La compilación falla con la MissingMethodException .

Con CameraPresent2() , la llamada al captador de CameraEnabled solo se compila cuando se llama a CameraE() por primera vez, lo que nunca sucede.


Mirando el problema como se informó, parece no tener sentido. Las dos versiones deben ser idénticas. Sin embargo, me pregunto si el problema aquí es que la API de la cámara está usando la dynamic en algún momento, y está tratando de buscar un operador true() / false() / & . Esto podría convencerlo de cambiar a la lógica bool :

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


Solo una suposición alocada, pero ¿es posible que esto sea un problema de compilación JIT? Cuando se llama a CameraPresent1, ¿está intentando asignar la llamada Microsoft.WindowsMobile.Status.SystemState.CameraEnabled al dispositivo subyacente? Como no puede encontrar el método get_CameraEnabled, la función completa falla con una MissingMethodException.