Bret Walker
Bret Walker

Reputation: 1806

Can I use a List<T> as a collection of method pointers? (C#)

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!

Upvotes: 6

Views: 538

Answers (7)

aceinthehole
aceinthehole

Reputation: 5222

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.

Upvotes: 1

Joel Coehoorn
Joel Coehoorn

Reputation: 416059

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

Upvotes: 0

tvanfosson
tvanfosson

Reputation: 532595

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.

Upvotes: 1

brock.holum
brock.holum

Reputation: 3213

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

Upvotes: 2

David Alpert
David Alpert

Reputation: 3187

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)

Upvotes: 3

Khoth
Khoth

Reputation: 13328

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

Upvotes: 15

Maurice
Maurice

Reputation: 27632

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

Upvotes: 0

Related Questions