2009-06-02 2 views
25

Ho un elenco a discesa che viene compilato esaminando i metodi di una classe e compresi quelli che corrispondono a una firma specifica. Il problema è nel prendere l'elemento selezionato dall'elenco e ottenere il delegato a chiamare quel metodo nella classe. Il primo metodo funziona, ma non riesco a capire parte del secondo.Ottenere un delegato da methodinfo

Per esempio,

public delegate void MyDelegate(MyState state); 

public static MyDelegate GetMyDelegateFromString(string methodName) 
{ 
    switch (methodName) 
    { 
     case "CallMethodOne": 
      return MyFunctionsClass.CallMethodOne; 
     case "CallMethodTwo": 
      return MyFunctionsClass.CallMethodTwo; 
     default: 
      return MyFunctionsClass.CallMethodOne; 
    } 
} 

public static MyDelegate GetMyDelegateFromStringReflection(string methodName) 
{ 
    MyDelegate function = MyFunctionsClass.CallMethodOne; 

    Type inf = typeof(MyFunctionsClass); 
    foreach (var method in inf.GetMethods()) 
    { 
     if (method.Name == methodName) 
     { 
      //function = method; 
      //how do I get the function to call? 
     } 
    } 

    return function; 
} 

Come faccio ad avere la sezione commentata del secondo metodo di lavorare? Come faccio a trasmettere il numero MethodInfo al delegato?

Grazie!

Modifica: Ecco la soluzione di lavoro.

public static MyDelegate GetMyDelegateFromStringReflection(string methodName) 
{ 
    MyDelegate function = MyFunctionsClass.CallMethodOne; 

    Type inf = typeof(MyFunctionsClass); 
    foreach (var method in inf.GetMethods()) 
    { 
     if (method.Name == methodName) 
     { 
      function = (MyDelegate)Delegate.CreateDelegate(typeof(MyDelegate), method); 
     } 
    } 

    return function; 
} 

risposta

21

Avrai bisogno di chiamare qualche forma di Delegate.CreateDelegate(), a seconda se il metodo in questione è un metodo statico o istanza.

+1

Grazie nkohari, ha funzionato esattamente come ho bisogno. –

8
private static Delegate CreateDelegate(this MethodInfo methodInfo, object target) { 
    Func<Type[], Type> getType; 
    var isAction = methodInfo.ReturnType.Equals((typeof(void))); 
    var types = methodInfo.GetParameters().Select(p => p.ParameterType); 

    if (isAction) { 
     getType = Expression.GetActionType; 
    } 
    else { 
     getType = Expression.GetFuncType; 
     types = types.Concat(new[] { methodInfo.ReturnType }); 
    } 

    if (methodInfo.IsStatic) { 
     return Delegate.CreateDelegate(getType(types.ToArray()), methodInfo); 
    } 

    return Delegate.CreateDelegate(getType(types.ToArray()), target, methodInfo.Name); 
} 
+0

Questa dovrebbe essere la risposta accettata: risolve direttamente la domanda – Graviton

+1

@Graviton Dipende se si ha la firma del metodo come un tipo 'Delegare' o meno. In questo caso, il PO sembra indicare che può pre-assumere 'MyDelegate', nel qual caso Nate e la soluzione che l'OP ha incorporato sono i migliori. Questa, d'altra parte, è un'ottima risposta per la * altra * domanda, che è cosa fare se non si ha accesso ad un appropriato tipo 'Delegate' (cioè, in genere, si è ottenuto un' MethodInfo' out-of- il blu solo per nome) ... ma serve proprio un tipo di delegato per creare un delegato (un problema di pollo e uova ".NET" un po 'famigerato). –