2010-11-07 32 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