2010-11-07 240 views
19

我打电话给MethodInfo.Invoke()以通过反射执行一个函数。这个调用被封装在一个try/catch块中,但它仍然不会捕获我调用的函数抛出的异常。反射MethodInfo.Invoke()从方法内部捕获异常

我收到以下消息:

例外是未处理的用户。


为什么MethodInfo.Invoke()防止Invoke()以外的地方捕捉到的异常?
我该如何绕过它?

回答

22

编辑:据我了解你的问题,这个问题纯粹是一个IDE的问题;你不喜欢VS把这个调用MethodInfo抛出的异常视为未被捕获,当它显然不是。你可以在这里阅读如何解决这个问题:Why is TargetInvocationException treated as uncaught by the IDE?它似乎是一个错误/设计;但不管怎样,这个答案都列出了体面的解决方法。

在我看来,你有两个选择:

  1. 您可以使用MethodInfo.Invoke,赶上TargetInvocationException并检查其InnerException财产。您必须按照该答案中提到的方法解决IDE问题。

  2. 您可以在MethodInfo之外创建合适的Delegate,然后调用它。使用这种技术,抛出的异常不会被包装。此外,这种方法确实似乎与调试器很好地发挥;我没有收到任何“未捕获的异常”弹出窗口。

下面是突出了方法的一个例子:

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

你如何捕捉异常?通常,从Invoke()调用中抛出的是System.Reflection.TargetInvocationException的包装异常实例。你遇到的实际例外将在InnerException

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

短期和简单的解决方案! – 2017-09-01 08:09:35