2009-06-02 6 views
25

J'ai une liste déroulante qui est remplie en inspectant les méthodes d'une classe et en incluant celles qui correspondent à une signature spécifique. Le problème consiste à prendre l'élément sélectionné dans la liste et à demander au délégué d'appeler cette méthode dans la classe. La première méthode fonctionne, mais je ne peux pas comprendre une partie de la seconde.Obtention d'un délégué à partir de methodinfo

Par exemple,

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

Comment puis-je obtenir de travailler la section commentée de la deuxième méthode? Comment puis-je diffuser le MethodInfo dans le délégué?

Merci!

Editer: Voici la solution de travail.

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

Répondre

21

Vous aurez besoin d'appeler une certaine forme de Delegate.CreateDelegate(), selon que la méthode en question est une méthode statique ou une instance.

+1

Merci nkohari, travaillé exactement comme j'ai besoin. –

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

Cela devrait être la réponse acceptée: il résout directement la question – Graviton

+1

@Graviton Cela dépend si vous avez la signature de la méthode en tant que type 'Delegate' ou non. Dans ce cas, l'OP semble indiquer qu'il peut pré-supposer 'MyDelegate', auquel cas Nate et la solution incorporée par OP sont les meilleures. Celui-ci, d'un autre côté, est une excellente réponse à la question * other *, qui est ce qu'il faut faire si vous n'avez pas accès à un type 'Delegate' approprié (typiquement, vous avez obtenu un' MethodInfo' out-of- le bleu par le nom seul) ... mais besoin précisément d'un tel type de délégué afin de créer un délégué (un problème de poulet et d'oeuf quelque peu notoire '.NET'). –

Questions connexes