2011-06-17 58 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); 
相關問題