HRESULT ed eccezioni

Per segnalare il verificarsi di un errore, i metodi COM restituiscono un HRESULT. I metodi .NET, invece, generano un'eccezione. Il runtime gestisce la transizione tra i due. Ogni classe che identifica un'eccezione in .NET Framework è associata a un HRESULT.

Le classi di eccezione definite dall'utente possono specificare un HRESULT appropriato. Impostando il campo HResult dell'oggetto di eccezione, tali classi di eccezione possono modificare dinamicamente l'HRESULT che deve essere restituito quando viene generata l'eccezione. Informazioni aggiuntive sull'eccezione vengono fornite al client tramite l'interfaccia IErrorInfo, che è implementata dall'oggetto .NET nel processo non gestito.

Se si crea una classe che estende System.Exception, sarà necessario impostare il campo HRESULT durante la costruzione. In caso contrario, sarà la classe base a assegnare il valore di HRESULT. È possibile associare nuove classi di eccezione a un HRESULT esistente fornendo il valore nel costruttore dell'eccezione. Nell'esempio che segue viene illustrato come creare una nuova classe di eccezione denominata NoAccessException e associarla all'HRESULT E_ACCESSDENIED:

Class NoAccessException : public ApplicationException
{
    NoAccessException {} {
    HResult = E_ACCESSDENIED; 
}
}
CMyClass::MethodThatThrows
{
throw new NoAccessException();
}

È possibile imbattersi in un programma (in qualsiasi linguaggio di programmazione) che utilizza contemporaneamente codice gestito e codice non gestito. Il gestore di marshalling personalizzato illustrato nel codice che segue utilizza ad esempio il metodo Marshal.ThrowExceptionForHR(int HResult) per generare un'eccezione con uno specifico valore di HRESULT. Il metodo esamina l'HRESULT e genera il tipo di eccezione appropriato. L'HRESULT del frammento di codice riportato di seguito genera ad esempio ArgumentException.

CMyClass::MethodThatThrows
{
    Marshal.ThrowExceptionForHR(COR_E_ARGUMENT);
}

Nella tabella che segue viene fornita la mappa completa delle associazioni tra ciascun HRESULT e la classe di eccezione di .NET Framework ad esso paragonabile.

HRESULT Eccezione .NET
MSEE_E_APPDOMAINUNLOADED AppDomainUnloadedException
COR_E_APPLICATION ApplicationException
COR_E_ARGUMENT o
E_INVALIDARG
ArgumentException
COR_E_ARGUMENTOUTOFRANGE ArgumentOutOfRangeException
COR_E_ARITHMETIC o
ERROR_ARITHMETIC_OVERFLOW
ArithmeticException
COR_E_ARRAYTYPEMISMATCH ArrayTypeMismatchException
COR_E_BADIMAGEFORMAT o ERROR_BAD_FORMAT BadImageFormatException
COR_E_COMEMULATE_ERROR COMEmulateException
COR_E_CONTEXTMARSHAL ContextMarshalException
COR_E_CORE CoreException
NTE_FAIL CryptographicException
COR_E_DIRECTORYNOTFOUND o
ERROR_PATH_NOT_FOUND
DirectoryNotFoundException
COR_E_DIVIDEBYZERO DivideByZeroException
COR_E_DUPLICATEWAITOBJECT DuplicateWaitObjectException
COR_E_ENDOFSTREAM EndOfStreamException
COR_E_TYPELOAD EntryPointNotFoundException
COR_E_EXCEPTION Exception
COR_E_EXECUTIONENGINE ExecutionEngineException
COR_E_FIELDACCESS FieldAccessException
COR_E_FILENOTFOUND o
ERROR_FILE_NOT_FOUND
FileNotFoundException
COR_E_FORMAT FormatException
COR_E_INDEXOUTOFRANGE IndexOutOfRangeException
COR_E_INVALIDCAST o
E_NOINTERFACE
InvalidCastException
COR_E_INVALIDCOMOBJECT InvalidComObjectException
COR_E_INVALIDFILTERCRITERIA InvalidFilterCriteriaException
COR_E_INVALIDOLEVARIANTTYPE InvalidOleVariantTypeException
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_MULTICASTNOTSUPPORTED MulticastNotSupportedException
COR_E_NOTFINITENUMBER NotFiniteNumberException
E_NOTIMPL NotImplementedException
COR_E_NOTSUPPORTED NotSupportedException
COR_E_NULLREFERENCE o
E_POINTER
NullReferenceException
COR_E_OUTOFMEMORY o

E_OUTOFMEMORY

OutOfMemoryException
COR_E_OVERFLOW OverflowException
COR_E_PATHTOOLONG o
ERROR_FILENAME_EXCED_RANGE
PathTooLongException
COR_E_RANK RankException
COR_E_REFLECTIONTYPELOAD ReflectionTypeLoadException
COR_E_REMOTING RemotingException
COR_E_SAFEARRAYTYPEMISMATCH SafeArrayTypeMismatchException
COR_E_SECURITY SecurityException
COR_E_SERIALIZATION SerializationException
COR_E_STACKOVERFLOW o
ERROR_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_THREADABORTED ThreadAbortException
COR_E_THREADINTERRUPTED ThreadInterruptedException
COR_E_THREADSTATE ThreadStateException
COR_E_THREADSTOP ThreadStopException
COR_E_TYPELOAD TypeLoadException
COR_E_TYPEINITIALIZATION TypeInitializationException
COR_E_VERIFICATION VerificationException
COR_E_WEAKREFERENCE WeakReferenceException
COR_E_VTABLECALLSNOTSUPPORTED VTableCallsNotSupportedException
Tutti gli altri HRESULT COMException

Per recuperare informazioni sull'errore, il client gestito deve esaminare i campi dell'oggetto di eccezione generato. Affinché l'oggetto di eccezione fornisca informazioni utili su un errore, è necessario che l'oggetto COM implementi l'interfaccia IErrorInfo. Il runtime utilizza le informazioni fornite da IErrorInfo per inizializzare l'oggetto di eccezione.

Se l'oggetto COM non supporta IErrorInfo, il runtime inizializzerà un oggetto di eccezione con i valori predefiniti. Nella tabella che segue vengono elencati tutti i campi associati a un oggetto di eccezione e viene identificata l'origine delle informazioni predefinite adottata quando l'oggetto COM supporta IErrorInfo.

Campo di eccezione Origine delle 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 (in Visual Basic Nothing).
Message Stringa restituita da IErrorInfo->GetDescription.
Source Stringa restituita da IErrorInfo->GetSource.
StackTrace La traccia dello stack.
TargetSite Il nome del metodo che ha restituito l'HRESULT di errore.

I campi di eccezione, quali Message, Source e StackTrace, non sono disponibili per StackOverflowException.

Vedere anche

Interoperabilità COM avanzata | Gestione e generazione di eccezioni