2011-06-17 24 views
2

为什么不能正常工作?如何使用Compile在表达式<Action<T>>上调用DynamicInvoke?

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

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

当你调用

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

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

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

注意你的行动是

m => m.DoSomething(1). 

所以,你的行动由m需要的TestClass你所参数化的实例,并在该实例上调用m.DoSomething(1)。现在,当你动态调用这个方法时,你需要给它一个TestClass的实例。你没有这样做。

1

由于所定义的参数类型

Expression<Action<T>> 

该函数将需要根据以下代表表达式:

Action<TestClass> 

它是:在此基础上的

public void SampleMethod(TestClass a) 

正确的调用应该如下所示:

var t = new TestClass(); 
call.Compile().DynamicInvoke(t); 
相关问题