2010-11-14 5 views
4

J'ai un System.Reflection.MethodInfo et j'aimerais avoir une méthode qui crée un délégué (de préférence un Func < ...> ou une Action < ...>) qui représente cette méthode , donné une instance pour l'invoquer.Créer un délégué avec des paramètres arbitraires

Donc, idéalement, je voudrais quelque chose comme le psuedo-code suivant:

public TDelegate GetMethod<TDelegate>(MethodInfo methodToRepresent, object instanceToInvokeOn) 
{ 
    return (TDelegate)((parameters....) => methodToRepresent.Invoke(instanceToInvokeOn, all parameters in an object[])); 
} 

où TDelegate représente la signature de la méthode représentée. Si les signatures ne correspondent pas, une exception doit être levée.

Je me rends compte que je ne peux probablement pas réaliser cela avec une expression lambda simple, puisque ses parametertypes doivent être connus à la compilation. Peut-être que j'ai besoin de construire un délégué à partir de zéro? Est-il possible de créer un délégué en spécifiant son corps et ses paramètres séparément?

Merci

Répondre

3

Je ne comprends pas vraiment votre question. Mais peut-être que vous voulez cela:

public TDelegate GetMethod<TDelegate>(MethodInfo methodToRepresent, object instanceToInvokeOn) 
    where TDelegate:class 
{ 
    return (TDelegate)(object)Delegate.CreateDelegate(typeof(TDelegate), instanceToInvokeOn, methodToRepresent); 
} 
+0

Merci, je n'étais pas au courant des méthodes Delegate.CreateDelegate. – JBSnorro

2

Vous pouvez le faire avec la méthode suivante. Notez que vous ne pouvez pas vraiment créer un Action<...> générique en utilisant cette méthode car, comme vous le dites, les types ne sont pas connus au moment de la compilation. Mais cela vous rapproche assez.

public delegate void DynamicInvokeDelegate(params object[] args); 

public static DynamicInvokeDelegate CreateDynamicInvokeDelegate(MethodInfo method, object instance) { 
    return args => method.Invoke(instance, args); 
} 

Si vous avez besoin du délégué pour retourner une valeur:

public delegate object DynamicInvokeWithReturnDelegate(params object[] args); 

public static DynamicInvokeWithReturnDelegate CreateDynamicInvokeWithReturnDelegate(MethodInfo method, object instance) { 
    return args => method.Invoke(instance, args); 
} 

EDIT:

Il ressemble vraiment à vous manquât ce code:

public static T GetDelegate<T>(MethodInfo method, object instance) 
    where T : class 
{ 
    return (T)(object)Delegate.CreateDelegate(typeof(T), instance, method); 
} 

Le cast (object) est requis, car le compilateur ne permettra pas vous pouvez utiliser Delegate pour n'importe quel type aléatoire et vous ne pouvez pas contraindre T à être un délégué. La conversion d'un objet satisfait le compilateur.

+0

wow nous avons obtenu le code très similaire – CodesInChaos

+0

Yup, c'est à peu près identique. Je n'aurais pas réglé pour la solution avec l'objet params [], cependant. Thnx de toute façon – JBSnorro

+0

OT: mais je voulais juste dire bienvenue et félicitations après une première semaine très réussie et active sur stackoverflow. Merci de contribuer; p –

Questions connexes