Reflection MethodInfo.Invoke () capta excepciones desde el interior del método

Tengo una llamada a 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 invoca.

Recibo el siguiente mensaje:

La excepción no fue controlada por el usuario.

¿Por qué MethodInfo.Invoke() evita que la excepción quede atrapada fuera de Invoke() ?
¿Cómo lo evito?

EDITAR: Según entiendo su problema, el problema es puramente IDE; no le gusta que VS trate la excepción lanzada por la invocación de MethodInfo como no MethodInfo , cuando claramente no lo es. Puede leer sobre cómo resolver este problema aquí: ¿Por qué TargetInvocationException es tratado como no capturado por el IDE? Parece ser un error / por diseño; pero de una manera u otra, las soluciones provisionales decentes se enumeran en esa respuesta.

Como yo lo veo, tienes un par de opciones:

  1. Puede usar MethodInfo.Invoke , atrapar la TargetInvocationException e inspeccionar su propiedad InnerException . Deberá solucionar los problemas de IDE mencionados en esa respuesta.

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

Aquí hay un ejemplo que destaca ambos enfoques:

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

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

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