2012-06-22 57 views
8

我想測試下面的代碼:我怎樣才能拋出一個特定的HResult異常?

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)。 –

回答

11

我找到了三種方法來做到這一點:

  1. 使用System.Runtime.InteropServices.ExternalException類,錯誤代碼作爲參數傳遞:

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

    感謝@HansPassant對他的評論解釋這一點。

    private class MockException : Exception 
    { 
        public MockException() { HResult = 0x4005; } 
    } 
    
    var ex = new MockException(); 
    
  2. 使用.NET反射來設置底層場:

    BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic; 
    FieldInfo hresultFieldInfo = typeof(Exception).GetField("_HResult", flags); 
    
    var ex = new Exception(); 
    hresultFieldInfo.SetValue(ex, 0x4005); 
    

傳遞的其中任何一個

  • 使用繼承訪問受保護的領域傳遞一個模擬異常該問題中方法的例外情況將導致該方法返回true。我懷疑第一種方法是最有用的。

  • 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; 
        } 
    } 
    
    相關問題