2010-11-07 18 views
19

Tengo una llamada al MethodInfo.Invoke() para ejecutar una función a través de la reflexión. La llamada está envuelta en un bloque try/catch pero aún no captará la excepción lanzada por la función que estoy invocando.Reflection MethodInfo.Invoke() capturas excepciones desde el interior del método

que recibe el mensaje siguiente:

excepción fue controlada por el usuario.


¿Por qué MethodInfo.Invoke() evitar la excepción a ser capturado fuera de la Invoke()?
¿Cómo lo evito?

Respuesta

22

EDIT: Como entiendo su problema, el problema es puramente IDE; no le gusta que VS trate la excepción lanzada por la invocación del MethodInfo como no detectada, cuando claramente no lo es. Puede leer sobre cómo resolver este problema aquí: Why is TargetInvocationException treated as uncaught by the IDE? Parece ser un error/por diseño; pero de una manera u otra, las soluciones provisionales decentes se enumeran en esa respuesta.

Tal como lo veo, usted tiene un par de opciones:

  1. Usted puede utilizar MethodInfo.Invoke, coger el TargetInvocationException e inspeccionar su propiedad InnerException. Deberá solucionar los problemas de IDE mencionados en esa respuesta.

  2. Puede crear un Delegate apropiado del MethodInfo e invocarlo en su lugar. Con esta técnica, la excepción arrojada no se verá envuelta. Además, este enfoque does parece jugar muy bien con el depurador; No recibo ninguna ventana emergente de "excepción no detectada".

Aquí hay un ejemplo que pone de relieve tanto se acerca:

class Program 
{ 
    static void Main() 
    { 
     DelegateApproach(); 
     MethodInfoApproach(); 
    } 

    static void DelegateApproach() 
    { 
     try 
     { 
      Action action = (Action)Delegate.CreateDelegate 
            (typeof(Action), GetMethodInfo()); 
      action(); 
     } 
     catch (NotImplementedException nie) 
     { 

     } 
    } 

    static void MethodInfoApproach() 
    { 
     try 
     { 
      GetMethodInfo().Invoke(null, new object[0]); 
     } 
     catch (TargetInvocationException tie) 
     { 
      if (tie.InnerException is NotImplementedException) 
      { 


      } 
     } 
    } 

    static MethodInfo GetMethodInfo() 
    { 
     return typeof(Program) 
       .GetMethod("TestMethod", BindingFlags.NonPublic | BindingFlags.Static); 
    }  

    static void TestMethod() 
    { 
     throw new NotImplementedException(); 
    } 
} 
15

¿Cómo intentas atrapar la excepción? Normalmente, lo que se lanza desde una llamada al Invoke() es una instancia de excepción de ajuste de System.Reflection.TargetInvocationException. La excepción real que está buscando estará en el InnerException.

try 
{ 
    method.Invoke(target, params); 
} 
catch (TargetInvocationException ex) 
{ 
    ex = ex.InnerException; // ex now stores the original exception 
} 
+0

solución a corto y simple! –

Cuestiones relacionadas