MethodInfo.Invoke with a delegate inside Object[] params
Let me try to give a little example.
class Session (
public delegate string CleanBody();
public static void Execute(string name, string q, CleanBody body) ...
can be used like:
Session.Execute("foo", "bar", delegate() { string x="beep"; /* whatever*/ return x; });
But what if I need to run is via MethodInfo.Invoke -- as in different dll no type dependen开发者_StackOverflowcies either way. Like:
Type type = Type.GetType("Bla.Session, FooSessionDll", true);
MethodInfo methodInfo = type.GetMethod("Execute");
Object [] args = { "foo", "bar", delegate() // Doesn't compile, now that ?
{
string x="beep"; /* whatever*/ return x;
}
methodInfo.Invoke("Trial Execution :-)", args);
Whatever trick/cast would be applied it would have to be such that it still arrives at Execute as a genuine delegate. Actual delegate(s) may have more complex signatures etc. etc.
private static class Invoker
{
private static string Method()
{
return "beep";
}
public static object Invoke()
{
Type type = Type.GetType("Bla.Session, FooSessionDll", true);
MethodInfo methodInfo = type.GetMethod("Execute");
Type delegateType = methodInfo.GetParameters()[2].ParameterType;
Delegate delegateInstance = Delegate.CreateDelegate(delegateType, typeof(Invoker).GetMethod("Method"));
object[] args = new object[] { "foo", "bar", delegateInstance };
return methodInfo.Invoke(null, args);
}
}
OK, found the solution: Func<<TResult>>
, and the whole family of Func templates. In terms of the example I posted, converting the signature of Execute(...) to:
public static void Execute(string name, string q, Func<string> body)
is functionally equivalent to the one with explicitly named delegate i.e. any code taking the type dependency on it can still use
Session.Execute("foo", "bar", delegate() { ... });
with zero code change, and any independent dll can now do:
Func<string> d = delegate() { .....}
and pass it in an Object[]
as a normal argument.
There was another thread asking "What’s so great about Func<>
" -- well this is :-)
It allows breaking dependencies and unholy tie-ups with zero code change for existing code that uses it. One condition is that existing code used anonymous methods (like in example) and not old-style explicit delegate creation.
精彩评论