2010-11-07 4 views
19

Ho una chiamata a MethodInfo.Invoke() per eseguire una funzione tramite riflessione. La chiamata è racchiusa in un blocco try/catch ma non catturerà comunque l'eccezione generata dalla funzione che sto invocando.Reflection MethodInfo.Invoke() cattura le eccezioni dall'interno del metodo

ricevo il seguente messaggio:

eccezione è stata gestita dall'utente.


Perché MethodInfo.Invoke() evitare che la deroga per essere catturati al di fuori della Invoke()?
Come lo escludo?

risposta

22

EDIT: Come ho capito il problema, il problema è puramente IDE; VS non ti piace che il trattamento dell'eccezione generata dall'invocazione dello MethodInfo come non risolto, quando chiaramente non lo è. Puoi leggere come risolvere questo problema qui: Why is TargetInvocationException treated as uncaught by the IDE? Sembra un bug/di progettazione; ma in un modo o nell'altro, in questa risposta sono elencati soluzioni alternative decenti.

come la vedo io, si dispone di un paio di opzioni:

  1. È possibile utilizzare MethodInfo.Invoke, prendere il TargetInvocationException e controllare la sua proprietà InnerException. Dovrai risolvere i problemi relativi all'IDE come menzionato in quella risposta.

  2. È possibile creare uno Delegate appropriato dal MethodInfo e richiamarlo. Con questa tecnica, l'eccezione generata non verrà spostata. Inoltre, questo approccio fa sembra giocare bene con il debugger; Non ricevo alcun pop-up "Eccezione non rilevata".

Ecco un esempio che mette in evidenza entrambi gli approcci:

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

Come stai cercando di rilevare l'eccezione? In genere ciò che viene generato da una chiamata a Invoke() è un'istanza di eccezione wrapping di System.Reflection.TargetInvocationException. L'eccezione effettiva che stai cercando sarà nello InnerException.

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

soluzione a breve e semplice! –