ExpressionTree作为接受任何方法的方法参数

时间:2016-09-01 20:15:27

标签: c# lambda expression-trees

我需要创建一个方法来检查作为参数传递的动态方法委托。但我不能强迫表达树接受任何方法,无论它们的签名如何。

这是我的方法(不编译:{{1​​}})

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

其中:

  • class Foo有方法:Examine<Foo>(x => foo1.Test1); Examine<Bar>(x => bar2.DifferentMethod2); // etc, with other methods
  • class Bar有方法:&#39; string DifferentMethod2(string a,string b)`
  • 和其他许多人

如何实现它?

注:

  • 我可以使用Func&lt;&gt;或行动&lt;&gt;因为将有许多可能的方法签名需要被参数类型接受,我将不会引用。

1 个答案:

答案 0 :(得分:4)

您必须使用FuncAction,但是您可以在调用者端而不是方法端使用它,因此您仍然可以接受任何类型。

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

这会创建一个类似

的表达式
.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)
}

.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)
}

进行两次调用。