Procedura: eseguire il mapping di HRESULT ed eccezioni
I metodi COM segnalano gli errori restituendo HRESULT, mentre i metodi .NET li segnalano generando eccezioni. Il runtime gestisce la transizione tra questi due approcci. Ogni classe di eccezione in .NET Framework viene mappata a un HRESULT.
Le classi di eccezioni definite dall'utente possono specificare un HRESULT appropriato. Queste classi di eccezione possono modificare dinamicamente il valore HRESULT da restituire quando viene generata l'eccezione impostando il campo HResult
per l'oggetto eccezione. Informazioni aggiuntive sull'eccezione vengono fornite al client tramite l'interfaccia IErrorInfo
, implementata per l'oggetto .NET nel processo non gestito.
Se si crea una classe che estende System.Exception
, è necessario impostare il campo HRESULT durante la costruzione. In caso contrario, la classe di base assegna il valore HRESULT. È possibile mappare nuove classi di eccezione a un HRESULT esistente specificando il valore nel costruttore dell'eccezione.
Si noti che il runtime a volte ignorerà un HRESULT
nei casi in cui nel thread è presente IErrorInfo
. Questo comportamento può verificarsi nei casi in cui HRESULT
e IErrorInfo
non rappresentano lo stesso errore.
Per creare una nuova classe di eccezione ed eseguirne il mapping a un HRESULT
Usare il codice seguente per creare una nuova classe di eccezione denominata
NoAccessException
ed eseguirne il mapping al valore HRESULTE_ACCESSDENIED
.Class NoAccessException : public ApplicationException { NoAccessException () { HResult = E_ACCESSDENIED; } } CMyClass::MethodThatThrows { throw new NoAccessException(); }
Possono esistere programmi, scritti con qualsiasi linguaggio, che usano codice gestito e non gestito contemporaneamente. Ad esempio, il gestore di marshalling personalizzato nell'esempio di codice seguente usa il metodo Marshal.ThrowExceptionForHR(int HResult)
per generare un'eccezione con un valore HRESULT specifico. Il metodo cerca il valore HRESULT e genera il tipo di eccezione appropriato. Ad esempio, il valore HRESULT nel frammento di codice seguente genera ArgumentException
.
CMyClass::MethodThatThrows
{
Marshal.ThrowExceptionForHR(COR_E_ARGUMENT);
}
La tabella seguente illustra i mapping comuni tra HRESULT e la classe di eccezioni corrispondente in .NET. I valori HRESULT senza mapping espliciti vengono mappati a COMException
. Il mapping aggiornato completo è disponibile nel repository dotnet/runtime.
HRESULT | Eccezione .NET |
---|---|
COR_E_APPLICATION |
ApplicationException |
COR_E_ARGUMENT oppure E_INVALIDARG |
ArgumentException |
COR_E_ARGUMENTOUTOFRANGE |
ArgumentOutOfRangeException |
COR_E_ARITHMETIC or ERROR_ARITHMETIC_OVERFLOW |
ArithmeticException |
COR_E_ARRAYTYPEMISMATCH |
ArrayTypeMismatchException |
COR_E_BADIMAGEFORMAT or ERROR_BAD_FORMAT |
BadImageFormatException |
COR_E_DIRECTORYNOTFOUND or ERROR_PATH_NOT_FOUND |
DirectoryNotFoundException |
COR_E_DIVIDEBYZERO |
DivideByZeroException |
COR_E_DUPLICATEWAITOBJECT |
DuplicateWaitObjectException |
COR_E_ENDOFSTREAM |
EndOfStreamException |
COR_E_ENTRYPOINTNOTFOUND |
EntryPointNotFoundException |
COR_E_EXCEPTION |
Exception |
COR_E_EXECUTIONENGINE |
ExecutionEngineException |
COR_E_FIELDACCESS |
FieldAccessException |
COR_E_FILENOTFOUND or ERROR_FILE_NOT_FOUND |
FileNotFoundException |
COR_E_FORMAT |
FormatException |
COR_E_INDEXOUTOFRANGE |
IndexOutOfRangeException |
COR_E_INVALIDCAST or E_NOINTERFACE |
InvalidCastException |
COR_E_INVALIDFILTERCRITERIA |
InvalidFilterCriteriaException |
COR_E_INVALIDOPERATION |
InvalidOperationException |
COR_E_IO |
IOException |
COR_E_MEMBERACCESS |
AccessException |
COR_E_METHODACCESS |
MethodAccessException |
COR_E_MISSINGFIELD |
MissingFieldException |
COR_E_MISSINGMANIFESTRESOURCE |
MissingManifestResourceException |
COR_E_MISSINGMEMBER |
MissingMemberException |
COR_E_MISSINGMETHOD |
MissingMethodException |
COR_E_NOTFINITENUMBER |
NotFiniteNumberException |
E_NOTIMPL |
NotImplementedException |
COR_E_NOTSUPPORTED |
NotSupportedException |
COR_E_NULLREFERENCE orE_POINTER |
NullReferenceException |
COR_E_OUTOFMEMORY or E_OUTOFMEMORY |
OutOfMemoryException |
COR_E_OVERFLOW |
OverflowException |
COR_E_PATHTOOLONG or ERROR_FILENAME_EXCED_RANGE |
PathTooLongException |
COR_E_RANK |
RankException |
COR_E_REFLECTIONTYPELOAD |
ReflectionTypeLoadException |
COR_E_SECURITY |
SecurityException |
COR_E_SERIALIZATION |
SerializationException |
COR_E_STACKOVERFLOW orERROR_STACK_OVERFLOW |
StackOverflowException |
COR_E_SYNCHRONIZATIONLOCK |
SynchronizationLockException |
COR_E_SYSTEM |
SystemException |
COR_E_TARGET |
TargetException |
COR_E_TARGETINVOCATION |
TargetInvocationException |
COR_E_TARGETPARAMCOUNT |
TargetParameterCountException |
COR_E_THREADINTERRUPTED |
ThreadInterruptedException |
COR_E_THREADSTATE |
ThreadStateException |
COR_E_TYPELOAD |
TypeLoadException |
COR_E_TYPEINITIALIZATION |
TypeInitializationException |
COR_E_VERIFICATION |
VerificationException |
Per recuperare informazioni dettagliate sull'errore, il client gestito deve esaminare i campi dell'oggetto eccezione generato. Affinché l'oggetto eccezione possa fornire informazioni utili su un errore, è necessario che l'oggetto COM implementi l'interfaccia IErrorInfo
. Il runtime usa le informazioni fornite da IErrorInfo
per inizializzare l'oggetto eccezione.
Se l'oggetto COM non supporta IErrorInfo
, il runtime Inizializza un oggetto eccezione con i valori predefiniti. La tabella seguente elenca ogni campo associato a un oggetto eccezione e identifica l'origine delle informazioni predefinite quando l'oggetto COM supporta IErrorInfo
.
Si noti che il runtime a volte ignorerà un HRESULT
nei casi in cui nel thread è presente IErrorInfo
. Questo comportamento può verificarsi nei casi in cui HRESULT
e IErrorInfo
non rappresentano lo stesso errore.
Campo eccezione | Fonte di informazioni da COM |
---|---|
ErrorCode |
HRESULT restituito dalla chiamata. |
HelpLink |
Se IErrorInfo->HelpContext è diverso da zero, la stringa viene formata concatenando IErrorInfo->GetHelpFile e "#" e IErrorInfo->GetHelpContext . In caso contrario, la stringa viene restituita da IErrorInfo->GetHelpFile . |
InnerException |
Sempre un riferimento null (Nothing in Visual Basic). |
Message |
Stringa restituita da IErrorInfo->GetDescription . |
Source |
Stringa restituita da IErrorInfo->GetSource . |
StackTrace |
Analisi dello stack. |
TargetSite |
Nome del metodo che ha restituito il valore HRESULT in errore. |
I campi eccezione, ad esempio Message
, Source
e StackTrace
non sono disponibili per StackOverflowException
.