17

次のコードをテストしたい:

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

Exceptionどうにかして正しい HResult を返すようにオブジェクトを設定したいのですが、Exceptionこれを許可するクラスのフィールドが見つかりません。

どうすればいいですか?

4

2 に答える 2

22

これを行うには、次の 3 つの方法を見つけました。

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

これらの例外のいずれかを問題のメソッドに渡すと、そのメソッドは を返しtrueます。最初の方法が最も有用であると思います。

于 2012-06-22T15:35:14.633 に答える
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;
    }
}
于 2013-09-13T02:57:57.630 に答える