代码之家  ›  专栏  ›  技术社区  ›  Austin Salonen gmlacrosse

C:返回给定对象和方法名的委托

  •  8
  • Austin Salonen gmlacrosse  · 技术社区  · 16 年前

    假设给我一个对象和一个包含方法名的字符串,我如何返回(该方法的)该方法的委托??

    例子:

    MyDelegate GetByName(ISomeObject obj, string methodName)
    {
        ...
        return new MyDelegate(...);
    }
    
    ISomeObject someObject = ...;
    MyDelegate myDelegate = GetByName(someObject, "ToString");
    
    //myDelegate would be someObject.ToString
    

    事先谢谢。

    还有一件事——我真的不想使用switch语句,尽管它可以工作,但是它是大量的代码。

    3 回复  |  直到 16 年前
        1
  •  21
  •   Jon Skeet    16 年前

    你需要使用 Type.GetMethod 找到正确的方法,以及 Delegate.CreateDelegate 转换 MethodInfo 成为代表。完整例子:

    using System;
    using System.Reflection;
    
    delegate string MyDelegate();
    
    public class Dummy
    {
        public override string ToString()
        {
            return "Hi there";
        }
    }
    
    public class Test
    {
        static MyDelegate GetByName(object target, string methodName)
        {
            MethodInfo method = target.GetType()
                .GetMethod(methodName, 
                           BindingFlags.Public 
                           | BindingFlags.Instance 
                           | BindingFlags.FlattenHierarchy);
    
            // Insert appropriate check for method == null here
    
            return (MyDelegate) Delegate.CreateDelegate
                (typeof(MyDelegate), target, method);
        }
    
        static void Main()
        {
            Dummy dummy = new Dummy();
            MyDelegate del = GetByName(dummy, "ToString");
    
            Console.WriteLine(del());
        }
    }
    

    不过,梅尔达德的评论是一个很好的评论——如果这个超负荷的 Delegate.CreateDelegate 好吧,你可以简化一下 GetByName 明显地:

        static MyDelegate GetByName(object target, string methodName)
        {
            return (MyDelegate) Delegate.CreateDelegate
                (typeof(MyDelegate), target, methodName);
        }
    

    我自己从来没有用过这个,因为我通常在找到 方法信息 明确地说——但在合适的地方,这真的很方便:)

        2
  •  3
  •   Mehrdad Afshari    16 年前
    static MyDelegate GetByName(object obj, string methodName)
    {
        return () => obj.GetType().InvokeMember(methodName, 
            System.Reflection.BindingFlags.InvokeMethod, null, obj, null); 
    }
    
        3
  •  1
  •   JoshBerke    16 年前

    更容易使用的是:

        public static MyDelegate GetByName(object target, string methodName)
        {
            return (MyDelegate)Delegate.CreateDelegate(typeof(MyDelegate), 
                   target, methodName);
        }
    

    请注意,CreateDelegate有一个重载,它为您采用methodName。这是用.NET 3.5 SP1完成的