如何使用某个HResult抛出异常?

时间:2012-06-22 14:37:47

标签: c# exception testing marshalling hresult

我想测试以下代码:

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

我想以某种方式设置Exception对象以返回正确的HResult,但我无法在Exception类中看到允许此字段的字段。

我该怎么做?

2 个答案:

答案 0 :(得分:15)

我找到了三种方法:

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

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

    感谢@HansPassant对他的评论进行解释。

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

    private class MockException : Exception
    {
        public MockException() { HResult = 0x4005; }
    }
    
    var ex = new MockException();
    
  3. 使用.NET Reflection设置基础字段:

    BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
    FieldInfo hresultFieldInfo = typeof(Exception).GetField("_HResult", flags);
    
    var ex = new Exception();
    hresultFieldInfo.SetValue(ex, 0x4005);
    
  4. 将这些异常中的任何一个传递给问题中的方法,将导致该方法返回true。我怀疑第一种方法最有用。

答案 1 :(得分:1)

我发现创建扩展程序很有用。

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;
    }
}