COM 方法通过返回 HRESULT 来报告错误;.NET 方法则通过引发异常来报告错误。运行库将处理这两者之间的转换。.NET Framework 中的每个异常类都会映射到一个 HRESULT。
用户定义的异常类可以指定任何适当的 HRESULT。当通过设置异常对象的 HResult 字段来生成异常时,这些异常类可以动态地更改所返回的 HRESULT。有关异常的其他信息通过 IErrorInfo 接口提供给客户端,该接口于非托管进程中在 .NET 对象上实现。
如果创建了扩展 System.Exception 的类,则必须在构造过程中设置 HRESULT 字段。否则,基类将分配 HRESULT 值。通过在异常的构造函数中提供 HRESULT 值,可以将新的异常类映射到现有的 HRESULT。
注意,当线程上存在 IErrorInfo 时,运行库有时会忽略 HRESULT。该行为可能发生在 HRESULT 和 IErrorInfo 不表示相同错误的情况下。
新建异常类并将其映射到 HRESULT
-
使用以下代码新建一个名为 NoAccessException 的异常类并将它映射到 HRESULT E_ACCESSDENIED。
{
NoAccessException () {
HResult = E_ACCESSDENIED;
}
}
CMyClass::MethodThatThrows
{
throw new NoAccessException();
}
您可能遇到过同时使用托管和非托管代码的程序(以任何编程语言编写)。例如,下面的代码示例中的自定义封送拆收器使用 Marshal.ThrowExceptionForHR(int HResult) 方法来引发具有特定 HRESULT 值的异常。该方法将查找此 HRESULT 并生成相应的异常类型。例如,下面的代码片段中的 HRESULT 将生成 ArgumentException。
{
Marshal.ThrowExceptionForHR(COR_E_ARGUMENT);
}
下表提供了从每个 HRESULT 到它在 .NET Framework 中的可比异常类的完整关系映射。
HRESULT | .NET 异常 |
---|---|
MSEE_E_APPDOMAINUNLOADED |
AppDomainUnloadedException |
COR_E_APPLICATION |
ApplicationException |
COR_E_ARGUMENT 或 E_INVALIDARG |
ArgumentException |
COR_E_ARGUMENTOUTOFRANGE |
ArgumentOutOfRangeException |
COR_E_ARITHMETIC 或 ERROR_ARITHMETIC_OVERFLOW |
ArithmeticException |
COR_E_ARRAYTYPEMISMATCH |
ArrayTypeMismatchException |
COR_E_BADIMAGEFORMAT 或 ERROR_BAD_FORMAT |
BadImageFormatException |
COR_E_COMEMULATE_ERROR |
COMEmulateException |
COR_E_CONTEXTMARSHAL |
ContextMarshalException |
COR_E_CORE |
CoreException |
NTE_FAIL |
CryptographicException |
COR_E_DIRECTORYNOTFOUND 或 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 或 ERROR_FILE_NOT_FOUND |
FileNotFoundException |
COR_E_FORMAT |
FormatException |
COR_E_INDEXOUTOFRANGE |
IndexOutOfRangeException |
COR_E_INVALIDCAST 或 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 或 E_POINTER |
NullReferenceException |
COR_E_OUTOFMEMORY 或 E_OUTOFMEMORY |
OutOfMemoryException |
COR_E_OVERFLOW |
OverflowException |
COR_E_PATHTOOLONG 或 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 或 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 |
其他所有 HRESULT |
COMException |
要检索扩展的错误信息,托管客户端必须检查已生成的异常对象的字段。要让异常对象提供有关错误的有用信息,COM 对象必须实现 IErrorInfo 接口。运行库使用 IErrorInfo 所提供的信息来初始化异常对象。
如果 COM 对象不支持 IErrorInfo,运行库将用默认值初始化异常对象。下表列出了与异常对象相关联的每个字段,并说明了当 COM 对象支持 IErrorInfo 时的默认信息源。
注意,当线程上存在 IErrorInfo 时,运行库有时会忽略 HRESULT。该行为可能发生在 HRESULT 和 IErrorInfo 不表示相同错误的情况下。
异常字段 | COM 信息源 |
---|---|
ErrorCode |
调用返回的 HRESULT。 |
HelpLink |
如果 IErrorInfo->HelpContext 不为零,字符串将通过串联 IErrorInfo->GetHelpFile 和“#”和 IErrorInfo->GetHelpContext 来形成。否则,字符串将从 IErrorInfo->GetHelpFile 返回。 |
InnerException |
始终为空引用(在 Visual Basic 中为 Nothing)。 |
Message |
IErrorInfo->GetDescription 返回的字符串。 |
Source |
IErrorInfo->GetSource 返回的字符串。 |
StackTrace |
堆栈跟踪。 |
TargetSite |
返回失败 HRESULT 的方法的名称。 |
Message、Source 和 StackTrace 等异常字段不可用于 StackOverflowException。