2012-06-22 12 views
8

Quiero probar el siguiente código:¿Cómo puedo lanzar una excepción con un determinado HResult?

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

Me gustaría configurar el objeto Exception alguna manera para devolver el HResult correcto, pero no puedo ver un campo en la clase Exception que permite esto.

¿Cómo podría hacer esto?

+1

La clase de excepción base para este tipo de excepciones es ExternalException. Tiene una propiedad pública ErrorCode con un constructor para configurarlo. La clase COMException 'HRESULT predeterminada ya es 0x80004005 (E_FAIL). –

Respuesta

11

He encontrado tres maneras de hacer esto:

  1. utilizar la clase System.Runtime.InteropServices.ExternalException, pasando el código de error como parámetro:

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

    Gracias a @HansPassant para su comentario explicando esto.

  2. pasar una excepción maqueta utilizando la herencia para acceder a un campo de protección:

    private class MockException : Exception 
    { 
        public MockException() { HResult = 0x4005; } 
    } 
    
    var ex = new MockException(); 
    
  3. Uso .NET reflexión para establecer el campo subyacente:

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

Pasando cualquiera de estos Las excepciones al método en la pregunta darán lugar a que el método devuelva true. Sospecho que el primer método es más útil.

1

Encuentro útil crear una extensión para hacer esto.

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

luego tirar excepción:

using Helper; 

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