2

让我试着举一个小例子。

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。实际代表可能有更复杂的签名等。

4

2 回答 2

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);
    }
}
于 2010-06-24T03:20:55.043 回答
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<>”——嗯,这是:-)

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

于 2010-06-24T22:27:01.487 回答