代码之家  ›  专栏  ›  技术社区  ›  ZXX

MethodInfo.Invoke,在对象[]参数中使用委托

  •  1
  • ZXX  · 技术社区  · 14 年前

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

    2 回复  |  直到 14 年前
        1
  •  0
  •   ChaosPandion    14 年前
    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);
        }
    }
    
        2
  •  0
  •   Christian    11 年前

    好的,找到了解决办法: 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<> “--嗯,这是:-)

    它允许使用它的现有代码在零代码更改的情况下打破依赖关系和不神圣的联系。一个条件是现有代码使用匿名方法(如示例中所示),而不是老式的显式委托创建。