如何使用特定的HResult引发异常?

17

我想测试以下代码:

private bool TestException(Exception ex)
{
    if ((Marshal.GetHRForException(ex) & 0xFFFF) == 0x4005)
    {
        return true;
    }
    return false;
}

我想以某种方式设置Exception对象来返回正确的HResult,但我在Exception类中找不到允许这样做的字段。

我该如何做?


1
这类异常的基本异常类是ExternalException。它有一个公共的ErrorCode属性和一个用于设置它的构造函数。COMException类的默认HRESULT已经是0x80004005(E_FAIL)。 - Hans Passant
2个回答

22

我找到了三种方法来实现这个:

  1. 使用 System.Runtime.InteropServices.ExternalException 类,将错误代码作为参数传递:

    var ex = new ExternalException("-", 0x4005);
    

    感谢@HansPassant的评论,解释了这个问题。

  2. 使用继承传递模拟异常来访问受保护字段:

  3. private class MockException : Exception
    {
        public MockException() { HResult = 0x4005; }
    }
    
    var ex = new MockException();
    
    使用.NET反射来设置底层字段:
    BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
    FieldInfo hresultFieldInfo = typeof(Exception).GetField("_HResult", flags);
    
    var ex = new Exception();
    hresultFieldInfo.SetValue(ex, 0x4005);
    
    传递这些异常中的任何一个到该问题的方法中,将导致该方法返回true。我认为第一个方法最有用。

2
我觉得创建一个扩展程序来完成这个任务很有用。
using System.Reflection;

namespace Helper
{
    public static class ExceptionHelper 
    {
       public static Exception SetCode(this Exception e, int value)
       {
           BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
           FieldInfo fieldInfo = typeof(Exception).GetField("_HResult", flags);

           fieldInfo.SetValue(e, value);

           return e;
        }
}

然后抛出异常:

using Helper;

public void ExceptionTest()
{
    try
    {
        throw new Exception("my message").SetCode(999);
    }
    catch (Exception e)
    {
        string message = e.Message;
        int code = e.HResult;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接