Vedere sotto per una spiegazione di ciò che sta accadendo.NET eccezione catturato è inaspettatamente nulla
Ho un problema davvero strano dove l'eccezione catturato è nullo.
Il codice utilizza MEF e cerca di segnalare errori di composizione. Usando il debugger posso vedere l'eccezione lanciata (un InvalidOperationException
) ma quando viene catturata dall'ultimo blocco catch nel codice sotto la variabile ex
è nullo. Questo è vero sia nel debugger che durante l'esecuzione normale del codice.
static T ResolveWithErrorHandling<T>() where T : class
{
try
{
IocContainer.Compose(Settings.Default.IocConfiguration);
return IocContainer.Resolve<T>();
}
catch (ReflectionTypeLoadException ex)
{
// ... special error reporting for ReflectionTypeLoadException
}
catch (Exception ex)
{
// ex is null - that should not be possible!
// ... general error reporting for other exception types
}
return null;
}
Il codice che ho sostituito con i commenti è codice molto semplice per formattare il messaggio di errore. Non succede niente di strano.
ho cercato di modificare il codice di scoprire che effetto che potrebbe avere:
- Se rimuovo il primo blocco catch (
ReflectionTypeLoadException
) l'eccezione catturato nel blocco catch finale è non è più nulla. - Se rilevo un altro tipo di eccezione nel primo blocco catch, l'eccezione rilevata nel blocco catch finale non è più nulla.
- Se aggiungo un blocco catch per
InvalidOperationException
come primo blocco catch, l'eccezione rilevata in quel blocco non è nulla. - Se aggiungo un blocco catch per
InvalidOperationException
tra i due blocchi catch, l'eccezione rilevata in quel blocco è null.
Il progetto utilizza Code Contracts e il codice generato dal compilatore è post-elaborato per verificare i contratti. Sfortunatamente, non ho trovato un modo per sbarazzarmi di questo a scopo di test senza eseguire un intervento chirurgico importante sul progetto.
La mia soluzione attuale è quella di non intercettare ReflectionTypeLoadException
e diramare invece il tipo di ex
nel gestore di eccezioni generale.
Quale potrebbe essere la spiegazione di questo comportamento "impossibile"? Che succede con il blocco catch ReflectionTypeLoadException
?
In modo imbarazzante, l'eccezione non è nulla e non può essere nullo per lo standard C# 15.9.5.
Tuttavia, l'utilizzo di Contratti di codice in un progetto can mess up the display of local variables in the debugger poiché il codice IL generato dal compilatore può essere riscritto dai Contratti di codice in modo che l'IL finale non sia leggermente sincronizzato con le informazioni di debug. Nel mio caso la variabile ex
viene visualizzata come null anche se non lo è. La sfortunata natura della segnalazione degli errori avvenuta proprio prima della chiusura della domanda ha significato che ritenevo che l'errore di segnalazione non fosse chiamato a causa del fatto che ex
era nullo e ex.Message
che lanciava uno NullReferenceException
nel mio blocco di cattura. Usando il debugger sono stato in grado di "verificare" che ex
fosse nullo, tranne che in realtà non era nulla.
La mia confusione è stata aggravata dal fatto che un blocco catch per ReflectionTypeLoadException
sembra influenzare il problema di visualizzazione del debugger.
Grazie a tutti coloro che hanno risposto.
Esiste effettivamente un 'ReflectionTypeLoadException' che viene lanciato ovunque? – Jaymz
Solo una nota, ma puoi gestire i diversi tipi di eccezione o stai solo segnalando lo stesso per ciascuno? Se si tratta di rapporti generici e non è possibile _handle_ l'eccezione, non sono sicuro che sarà necessario adattare le interferenze in ogni caso. –
Cosa succede quando si aggiunge una cattura per InvalidOperationExecption? –