Могу ли я использовать List <T>как набор указателей методов? (С #) - PullRequest
6 голосов
/ 25 сентября 2008

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

«метод» является «переменной», но используется как «метод»

Теоретически, вот что я хотел бы сделать:

List<object> methodsToExecute;

int Add(int x, int y)
{ return x+y; }

int Subtract(int x, int y)
{ return x-y; }

delegate int BinaryOp(int x, int y);

methodsToExecute.add(new BinaryOp(add));
methodsToExecute.add(new BinaryOp(subtract));

foreach(object method in methodsToExecute)
{
    method(1,2);
}

Есть идеи, как этого добиться? Спасибо!

Ответы [ 7 ]

15 голосов
/ 25 сентября 2008

Вам необходимо привести object в списке к BinaryOp или, что лучше, использовать более конкретный параметр типа для списка:

delegate int BinaryOp(int x, int y);

List<BinaryOp> methodsToExecute = new List<BinaryOp>();

methodsToExecute.add(Add);
methodsToExecute.add(Subtract);

foreach(BinaryOp method in methodsToExecute)
{
    method(1,2);
}
3 голосов
/ 25 сентября 2008

Используя .NET 3.0 (или 3.5?), У вас есть общие делегаты.

Попробуйте это:

List<Func<int, int, int>> methodsToExecute = new List<Func<int, int, int>>();

methodsToExecute.Add(Subtract);

methodsToExecute.Add[0](1,2); // equivalent to Subtract(1,2)
2 голосов
/ 25 сентября 2008
List<Func<int, int, int>> n = new List<Func<int, int, int>>();
            n.Add((x, y) => x + y);
            n.Add((x, y) => x - y);
            n.ForEach(f => f.Invoke(1, 2));
1 голос
/ 26 сентября 2008

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

1 голос
/ 25 сентября 2008

Мне нравится реализация Хота, но я думаю, что причина вашей ошибки компилятора в том, что вы не приводите метод к BinaryOp, прежде чем пытаться вызвать его. В вашем цикле foreach это просто «объект». Измените свой foreach, чтобы он выглядел так, как у Кота, и я думаю, что это сработает.

0 голосов
/ 25 сентября 2008

Не пробовал, но можно использовать тип List >.

0 голосов
/ 25 сентября 2008

Пусть все они реализуют общий интерфейс, скажем, IExecuteable, а затем список

Также, используя делегатов:

class Example
{
    public delegate int AddDelegate(int x, int y);

    public List<AddDelegate> methods = new List<AddDelegate>();

    int Execute()
    {
        int sum = 0;
        foreach(AddDelegate method in methods)
        {
            sum+=method.Invoke(1, 2);
        }
        return sum;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...