简体   繁体   中英

C#: Return a delegate given an object and a method name

Suppose I'm given an object and a string that holds a method name, how can I return a delegate to that method (of that method?) ?

Example:

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

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

//myDelegate would be someObject.ToString

Thanks in advance.

One more thing -- I really don't want to use a switch statement even though it would work but be a ton of code.

You'll need to use Type.GetMethod to get the right method, and Delegate.CreateDelegate to convert the MethodInfo into a delegate. Full example:

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's comment is a great one though - if the exceptions thrown by this overload of Delegate.CreateDelegate are okay, you can simplify GetByName significantly:

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

I've never used this myself, because I normally do other bits of checking after finding the MethodInfo explicitly - but where it's suitable, this is really handy :)

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

Even easier is to use:

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

Notice that CreateDelegate has an overload which takes the methodName for you. This was done with .net 3.5 Sp1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM