开发者

MethodInfo.Invoke with a delegate inside Object[] params

开发者 https://www.devze.com 2023-01-05 01:07 出处:网络
Let me try to give a little example. class Session ( public delegate string CleanBody(); public static void Execute(string name, string q, CleanBody body) ...

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消