C #: вернуть делегат с данным объектом и именем метода - PullRequest
8 голосов
/ 23 апреля 2009

Предположим, мне дан объект и строка, содержащая имя метода. Как я могу вернуть делегата этому методу (этого метода?)?

Пример:

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

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

//myDelegate would be someObject.ToString

Заранее спасибо.

Еще одна вещь - я действительно не хочу использовать оператор switch, даже если он будет работать, но это будет тонна кода.

Ответы [ 3 ]

21 голосов
/ 23 апреля 2009

Вам нужно будет использовать 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);
    }

Я никогда не использовал это сам, потому что я обычно выполняю другие проверки после нахождения MethodInfo явно - но там, где это подходит, это действительно удобно:)

3 голосов
/ 23 апреля 2009
static MyDelegate GetByName(object obj, string methodName)
{
    return () => obj.GetType().InvokeMember(methodName, 
        System.Reflection.BindingFlags.InvokeMethod, null, obj, null); 
}
1 голос
/ 23 апреля 2009

Еще проще в использовании:

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

Обратите внимание, что CreateDelegate имеет перегрузку, которая принимает methodName для вас. Это было сделано с .net 3.5 Sp1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...