Как я могу передать имя метода другому методу и вызвать его через переменную делегата? - PullRequest
3 голосов
/ 20 мая 2011

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

Как это можно сделать?Используя отражение?Func<T>?

Редактировать:

Теперь я понимаю, что отражение может быть не лучшим решением.

Это то, что у меня есть:

private static void MethodContainingDelegate(string methodNameInOtherClassAsString)
{
        _listOfSub.ForEach(delegate(Callback callback)
        {
            //Here the first works, but I want the method to be general and   
            //  therefore pass the method name as a string, not specfify it. 
            callback.MethodNameInOtherClass(); 
            //This below is what I am trying to get to work. 
             callback.MethodNameInOtherClassAsString();                  
          }
     });
}

Итак, я в основном ищу способ заставить моего делегата обратного вызова "распознавать", что мой methodNameInOtherClassAsString на самом деле является методом для выполнения вдругой класс.

Спасибо!

Ответы [ 3 ]

3 голосов
/ 20 мая 2011

Это очень просто:

public delegate void DelegateTypeWithParam(object param);
public delegate void DelegateTypeWithoutParam();

public void MethodWithCallbackParam(DelegateTypeWithParam callback, DelegateTypeWithoutParam callback2)
{
    callback(new object());
    Console.WriteLine(callback.Method.Name);
    callback2();
    Console.WriteLine(callback2.Method.Name);
}

// must conform to the delegate spec
public void MethodWithParam(object param) { }
public void MethodWithoutParam() { }

public void PassCallback()
{
   MethodWithCallbackParam(MethodWithParam, MethodWithoutParam);
}

Не имеет значения, на какой класс указывает переменная-делегат.Это может быть определено в другом классе - нет большой разницы.

Я думаю, вы могли бы даже запросить имя исходного метода из самой переменной делегата без отражения.У каждого делегата есть свойство с именем Method именно для этого.

2 голосов
/ 20 мая 2011

Вы можете сделать что-то вроде этого:

var mi = typeof(Foo).GetMethods().Single(x => x.Name == "Bar");
mi.Invoke(foo, null);

Где Foo - ваш целевой класс, Bar - метод, который вы хотите вызвать. Но вы должны отметить, что рефлексия окажет большое влияние на производительность вашей программы. Попробуйте вместо этого использовать строго типизированные делегаты.

0 голосов
/ 20 мая 2011

Предполагается, что у вас есть строковое представление имени метода:

var methodInfo = myObject.GetType().GetMethod(myString); //<- this can throw or return null
methodInfo.Invoke(myObject, new object[n]{parm1, pram2,...paramn});

вам, очевидно, нужно добавить некоторую проверку ошибок и использовать более конкретную версию GetMethod , если можете.

...