views:

387

answers:

7

I want to create a list of methods to execute. Each method has the same signature. I thought about putting delegates in a generic collection, but I keep getting this error:

'method' is a 'variable' but is used like a 'method'

In theory, here is what I would like to do:

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

Any ideas on how to accomplish this? Thanks!

A: 

Have them all implement of common interface, say IExecuteable, and then have a List<IExecutable>

Also, using delegates:

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;
    }
}
Joel Coehoorn
A: 

Haven't tried it but using an List< Action< t>> type should be able to do it.

Maurice
+15  A: 

You need to cast the object in the list to a BinaryOp, or, better, use a more specific type parameter for the list:

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);
}
Khoth
+3  A: 

Using .NET 3.0 (or 3.5?) you have generic delegates.

Try this:

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)
David Alpert
Shouldn't that last line be:methodsToExecute[0](1,2);or even beeter:int n = methodsToExecute[0](1,2);
James Curran
+2  A: 
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));
muloh
+1  A: 

I like Khoth's implementation better but I think what is causing your compiler error is that you don't cast method to a BinaryOp before you try to invoke it. In your foreach loop it is merely an "object". Change your foreach to look like Khoth's and I think it would work.

tvanfosson
+1  A: 

Whenever I have been tempted to do something like this, I have found that it is generally better to refactor your design to use the command pattern, especially since all of your methods have the same parameters. This way allows for far more flexibility.

aceinthehole