MethodInfo.Invoke with Object [] params中的委托

时间:2010-06-24 03:16:46

标签: c# delegates anonymous-methods

让我试着举个例子。

class Session (
    public delegate string CleanBody();
    public static void Execute(string name, string q, CleanBody body) ...

可以像:

一样使用
Session.Execute("foo", "bar", delegate() { string x="beep"; /* whatever*/ return x; });

但是如果我需要运行的是通过MethodInfo.Invoke - 就像在不同的dll中没有任何类型的依赖关系。像:

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);

无论应用什么技巧/演员,它都必须是这样的,它仍然作为真正的代表到达Execute。实际代表可能有更复杂的签名等等。

2 个答案:

答案 0 :(得分:0)

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);
    }
}

答案 1 :(得分:0)

好的,找到了解决方案:Func<<TResult>>,以及整个Func模板系列。就我发布的示例而言,将Execute(...)的签名转换为:

public static void Execute(string name, string q, Func<string> body) 

在功能上等同于具有显式命名委托的那个,即任何对其具有类型依赖性的代码仍然可以使用

Session.Execute("foo", "bar", delegate() { ... });

代码更改为零,任何独立的dll现在都可以执行:

Func<string> d = delegate() { .....} 

并将其作为正常参数传递给Object[]

还有另一个帖子问“Func<>有什么好处” - 这就是: - )

它允许打破依赖关系和不合理的绑定,对使用它的现有代码进行零代码更改。一个条件是现有代码使用匿名方法(如示例中)而不是旧式显式委托创建。