28

I'm trying to create a list that contains methods, and after I add some methods I want to execute them, is this possible?

I tried something like this:

List<object> methods = new List<object>();

Then:

methods.Add(Move());

But When I add, the program will call the methods, for example, in this case it called for Move();

Zhafur
  • 1,611
  • 1
  • 13
  • 30
user3491915
  • 307
  • 1
  • 3
  • 5

4 Answers4

54

This is a great use case for the Action generic delegate.

List<Action> functions = new List<Action>();
functions.Add(Move);

foreach (Action func in functions)
   func();

If you need parameters, I would use lambdas to abstract them away:

List<Action> functions = new List<Action>();
functions.Add(Move);
functions.Add(() => MoveTo(1, 5));

foreach (Action func in functions)
   func();

A delegate is akin to function pointers from C++, it holds what a function "is" (not a return value like in your example) so you can call it just like a regular function. The Action generic delegate takes no parameters and returns nothing, so it is ideal for generic "call these functions".

MSDN for Action: Action Delegate

For more on the different types of delegates provided by.NET: https://stackoverflow.com/a/567223/1783619

BradleyDotNET
  • 59,038
  • 10
  • 94
  • 113
  • Is making a `List` necessary? Seems like simply defining `Action yourFunction;` and appending the methods to it works by `+=` them, like so `yourFunction += DoThis; yourFunction += DoThat;`. Only downfall is, I'm not quite sure how it iterates it internally, so if you need that level of control a List may be more appropriate. – chamberlainpi Jul 26 '17 at 17:51
  • @bigp You can do this because all delegates are multicast. I personally like being explicit here; if I want to use += I'll just use an event. As you say, its basically a style thing though – BradleyDotNET Jul 26 '17 at 18:42
  • The original question doesn't require parameters and returns nothing but the *title question* likely means people coming here may be looking for something else. It might be worth adding a link to 'Further Reading'. I would do it myself but am not familiar enough with the language. – AnnanFay Feb 27 '20 at 15:44
  • 1
    @AnnanFay I added a link to some extra info, hopefully that addresses your concern – BradleyDotNET Feb 27 '20 at 16:45
  • 1
    cannot convert from 'method group' to 'Action', i see this error when i try to do this – ReZ Jul 14 '20 at 03:51
  • then one of your methods isn't a no parameter/void method. @ReZ – BradleyDotNET Jul 14 '20 at 04:17
  • I wrote something like this: List> methods = new List>(); methods.Add(mymethod); – ReZ Jul 14 '20 at 04:23
  • public void mymethod(int x) { Console.WriteLine(x); }, it's give me a compilation error An object reference is required for the non-static field, method, or property – ReZ Jul 14 '20 at 04:25
  • @ReZ High probability the call to `Add` is in a static method (main perhaps?) which can't access instance members (like `mymethod`) without an instance. – BradleyDotNET Jul 14 '20 at 14:28
  • Yeah i could fix it, i'm called add in Main, that is a static function, thanks for your help – ReZ Jul 14 '20 at 18:16
8

I'm not sure if this outside the scope of the original question (or will help anyone else), but I kept coming back to this page in my own search of how to create a list of return-type functions to iterate and execute. I ended up using the List<Func<T>> to create a list of type methods-

        bool RTrue()
        {
            Console.WriteLine("RETURNS TRUE");
            return true;
        }

        bool RFalse()
        {
            Console.WriteLine("RETURNS FALSE");
            return false;
        }

        List<Func<Boolean>> functions = new List<Func<Boolean>>();
        functions.Add(RTrue);
        functions.Add(RFalse);

        foreach (Func<Boolean> func in functions)
        {
            if (func() == true)
            {
                Console.WriteLine("IT WORKS");
            }
        }

Further info on Func usage- What is Func, how and when is it used

2

You can use delegates. Create a list of delegates. Then, for each method you want to add to the list, create a delegate and add to the list.

 List<Delegate> methods = new List<Delegate>();

 // creates an Action delegate implicitly
 methods.Add((Action)Move);
Mike Dinescu
  • 51,717
  • 14
  • 111
  • 144
0

Depending on what parameters are required:

var Actions = new List<Action<object, EventArgs>>
{
    ReconfirmOrderlines_Click,
    ModifyOrderlines_Click
};

Or, for example, when you want to create a list to use for dynamiclly adding items in a ContextMenuStrip with the text and Click event:

var actions = new List<(string, Action<object, EventArgs>)>
{
    ("Send confirmation", ReconfirmOrderlines_Click),
    ("Send modification", ModifyOrderlines_Click),
};

If you want to know what you need to enter inside of the list, I always use this 'trick': Trick to get the parameters

Jannick Breunis
  • 129
  • 2
  • 13