如何在Expression <action <t>&gt;上调用DynamicInvoke?使用Compile?</action <t>

时间:2011-06-17 20:47:25

标签: c# reflection lambda

为什么这不起作用?

namespace InvokeTest
{
    public class MethodInvoker
    {
        public static void Execute<T>(Expression<Action<T>> call)
        {
            // Parameter count mismatch
            call.Compile().DynamicInvoke();

            // Also attempted this:
            //call.Compile().DynamicInvoke(1);
            // but it threw: "Object of type 'System.Int32' cannot be converted to type 'InvokeTest.TestClass'."
        }
    }

    public class TestClass
    {
        public TestClass()
        { }

        public void DoSomething(int num)
        {
            System.Console.WriteLine("It works");
        }

        public void KickOff()
        {
            MethodInvoker.Execute<TestClass>(m => m.DoSomething(1));
        }
    }
}

2 个答案:

答案 0 :(得分:2)

Action<T>delegate void F<T>(T t)相同。也就是说,Action<T>是一种返回类型为void且使用T实例的方法。

致电时

MethodInvoker.Execute<TestClass>(m => m.DoSomething(1));

您已将类型参数T设置为TestClass。因此,您需要传入一个参数,该参数必须是TestClass的实例。

这就是为什么在第一种情况下你得到参数计数不匹配,而在第二种情况下,编译器想要将参数转换为TestClass的实例。您需要传递一个参数,该参数必须是TestClass的实例。

请注意,您的操作是

m => m.DoSomething(1).

因此,您的操作会使用TestClass的{​​{1}}实例进行参数化,并在该实例上调用m。现在,当您动态调用此方法时,您需要为其提供m.DoSomething(1)的实例。你不这样做。

答案 1 :(得分:1)

由于您定义了参数类型

Expression<Action<T>>

该函数将需要按照以下代理进行表达:

Action<TestClass>

是:

public void SampleMethod(TestClass a)

基于此,正确的调用应如下所示:

var t = new TestClass();
call.Compile().DynamicInvoke(t);