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

时间:2009-04-23 19:07:23

标签: c# reflection

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

示例:

MyDelegate GetByName(ISomeObject obj, string methodName)
{
    ...
    return new MyDelegate(...);
}

ISomeObject someObject = ...;
MyDelegate myDelegate = GetByName(someObject, "ToString");

//myDelegate would be someObject.ToString

提前致谢。

还有一件事 - 我真的不想使用switch语句,即使它可以工作但是需要很多代码。

3 个答案:

答案 0 :(得分:21)

您需要使用Type.GetMethod来获取正确的方法,并Delegate.CreateDelegateMethodInfo转换为委托。完整的例子:

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

Mehrdad的评论是一个很好的评论 - 如果Delegate.CreateDelegate的这个重载引发的例外是可以的,你可以大大简化GetByName

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

我自己从未使用过这个,因为我通常会在明确找到MethodInfo后进行其他检查 - 但是在适合的情况下,这非常方便:)

答案 1 :(得分:3)

static MyDelegate GetByName(object obj, string methodName)
{
    return () => obj.GetType().InvokeMember(methodName, 
        System.Reflection.BindingFlags.InvokeMethod, null, obj, null); 
}

答案 2 :(得分:1)

更容易使用:

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

请注意,CreateDelegate有一个重载,它为您获取methodName。这是通过.net 3.5 Sp1

完成的