How do I call DynamicInvoke on an Expression<Action<T>> using Compile?
Why doesn't this work?
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));
}
}
}
An Action<T>
is the same as a delegate void F<T>(T t)
. That is, an Action<T>
is an method that has return type void
and consumes instances of T
.
When you call
MethodInvoker.Execute<TestClass>(m => m.DoSomething(1));
you have set the type parameter T
to be TestClass
. Therefore, you need to pass in a parameter, and that parameter has to be instance of TestClass
.
This is why in the first case you get a parameter count mismatch, and in the second case the compiler wants to convert the parameter to an instance of TestClass
. You need to pass one parameter, and that parameter needs to be an instance of TestClass
.
Note that your action is
m => m.DoSomething(1).
So your action takes an instance of TestClass
which you are parameterizing by m
and invokes m.DoSomething(1)
on that instance. Now, when you dynamically invoke this method, you need to be giving it an instance of TestClass
. You aren't doing that.
Since you defined the parameter type
Expression<Action<T>>
the function will require expression in accordance with the following delegate:
Action<TestClass>
which is:
public void SampleMethod(TestClass a)
Based on this the correct invocation should look like this:
var t = new TestClass();
call.Compile().DynamicInvoke(t);
精彩评论