2016-09-01 4 views
2

Je dois créer une méthode qui examine dynamiquement le délégué de méthode passé en paramètre. Mais je ne peux pas forcer les arbres d'expression à accepter n'importe quelle méthode indépendamment de leur signature.ExpressionTree en tant que paramètre de méthode pour accepter n'importe quelle méthode

C'est ma méthode (ne compile pas: error CS0030: Cannot convert type 'method' to 'Delegate')

public void Examine<T>(Expression<Func<T, Delegate>> expression2) 
{ 
    // examine expression tree to get method name (MethodInfo) 
} 

Je veux l'appeler ainsi:

Examine<Foo>(x => foo1.Test1); 
Examine<Bar>(x => bar2.DifferentMethod2); 
// etc, with other methods 

où:

  • classe Foo a méthode : bool Test1(int num)
  • La barre de classe a la méthode: 'chaîne DifferentMethod2 (chaîne a, chaîne b) `
  • et bien d'autres

Comment y parvenir?

Remarque:

  • JE NE PEUX PAS utiliser Func <> ou action <> car il y aura de nombreuses signatures de méthode possibles qui doivent être acceptées avec les types de paramètres que je ne vais pas avoir une référence à.
+0

Ne l'avez pas testé, mais func ou action avec dynamique? charlatans comme un canard –

Répondre

4

Vous ne devez utiliser Func ou Action, vous pouvez toutefois l'utiliser sur le côté de l'appelant au lieu du côté de la méthode afin que vous puissiez accepter tout type.

static void Main() 
{ 
    Foo foo1 = null; 
    Bar bar2 = null; 
    Examine<Foo>(x => (Func<int,bool>)foo1.Test1); 
    Examine<Bar>(x => (Func<string,string,string>)bar2.DifferentMethod2); 
} 
public static void Examine<T>(Expression<Func<T, Delegate>> expression2) 
{ 
    // examine expression tree to get method name (MethodInfo) 
} 

Cela crée une expression comme

.Lambda #Lambda1<System.Func`2[SandboxConsole.Foo,System.Delegate]>(SandboxConsole.Foo $x) { 
    (System.Func`2[System.Int32,System.Boolean]).Call .Constant<System.Reflection.MethodInfo>(Boolean Test1(Int32)).CreateDelegate(
     .Constant<System.Type>(System.Func`2[System.Int32,System.Boolean]), 
     .Constant<SandboxConsole.Program+<>c__DisplayClass0_0>(SandboxConsole.Program+<>c__DisplayClass0_0).foo1) 
} 

et

.Lambda #Lambda1<System.Func`2[SandboxConsole.Bar,System.Delegate]>(SandboxConsole.Bar $x) { 
    (System.Func`3[System.String,System.String,System.String]).Call .Constant<System.Reflection.MethodInfo>(System.String DifferentMethod2(System.String, System.String)).CreateDelegate(
     .Constant<System.Type>(System.Func`3[System.String,System.String,System.String]), 
     .Constant<SandboxConsole.Program+<>c__DisplayClass0_0>(SandboxConsole.Program+<>c__DisplayClass0_0).bar2) 
} 

pour les deux invocations.