Perché il cortocircuito non impedisce MissingMethodException correlato al ramo irraggiungibile di AND logico (&&)?

Mentre eseguo un controllo se c’è una telecamera presente e abilitata sull’unità mobile Windows, ho riscontrato qualcosa che non capisco.

Il codice si presenta così:

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

Quando chiamo CameraPresent2() restituisce false (non è presente la telecamera). Ma quando chiamo CameraPresent1() un MissingMethodException con commento “Imansible trovare il metodo: get_CameraEnabled Microsoft.WindowsMobile.Status.SystemState.”

Il secondo termine è valutato in CameraPresent1 solo perché entrambi sono di proprietà (a livello di lingua)?

C’è qualcos’altro che spiega la differenza di comportamento?

Il secondo termine non è valutato.

Il primo termine non è valutato.

Il metodo CameraPresent1() non viene nemmeno avviato.

Quando chiami CameraPresent1() per la prima volta, il runtime deve JIT-compilare l’MSIL nel codice nativo. Ciò richiede la risoluzione di tutte le chiamate di metodo, anche quelle che potrebbero essere raggiunte solo in modo condizionale. La compilazione fallisce con MissingMethodException .

Con CameraPresent2() , la chiamata al getter di CameraEnabled viene compilata solo quando CameraE() viene chiamato per la prima volta, cosa che non succede mai.

C # Specifica sezione 7.12

Il && e || gli operatori sono chiamati operatori logici condizionali. Sono anche chiamati operatori logici “cortocircuiti”.

Il && e || gli operatori sono versioni condizionali di & e | operatori:

  • L’operazione x && y corrisponde all’operazione x & y , eccetto che y viene valutato solo se x non è false .

  • L’operazione x || y x || y corrisponde all’operazione x | y x | y , eccetto che y viene valutato solo se x non è true .


Ciò significa che la specifica C # garantisce che CameraE() venga chiamato se e solo se CameraP() è true.

Questo potrebbe essere un problema con ottimizzazioni aggressive del compilatore, e quindi il programma attuale sembra violare le specifiche della lingua …


Modificare:

È ansible creare un breakpoint e mostrare la finestra di disassemblaggio, per vedere il codice esatto generato?

Solo un’ipotesi, ma è ansible che questo sia un problema di compilazione JIT? Quando si chiama CameraPresent1, tenta di mappare la chiamata Microsoft.WindowsMobile.Status.SystemState.CameraEnabled al dispositivo sottostante? Poiché non riesce a trovare il metodo get_CameraEnabled, l’intera funzione non riesce con MissingMethodException.

Osservando il problema come riportato, sembra non avere senso. Le due versioni dovrebbero essere identiche. Mi chiedo, però, se il problema qui è che l’API della fotocamera sta usando la dynamic a un certo punto, e sta cercando di cercare un operatore true() / false() / & . Questo potrebbe convincerlo a passare alla logica bool :

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