How to Invoke a function in a List in C#

I'm fairly new to C# and trying to figure out how to invoke a function from a list. I thought that List would do the job I need it to. I can get my functions into the list, but I can't seem to actually invoke them.

First I tried this:

List<Action> randEvent = new List<Action>();

 void Test()
    {
        randEvent.Add(Test2);
        Invoke(randEvent(0), 0f);
    }

    void Test2()
    {
        print("This is a test of the random event system");
    }

Then this

   List<Action> randEvent = new List<Action>();

   void Test()
    {
        randEvent.Add(Test2);
        randEvent(0);
    }

    void Test2()
    {
        print("This is a test of the random event system");
    }

But neither works. What am I doing wrong? Is this even possible? The reason I want to do it this way is basically that I have 100 functions that I want my program to chose through at random when I call another function.

Any solution appreciated, though keep in mind I'm very new to C# and code in general still. Thanks in advance.

3 answers

  • answered 2018-02-13 02:06 John Woo

    You could declare sort of a list of Action and each object will point to a specific method. Example;

    IList<Action> actionList = new List<Action>();
    actionList.Add(() => Test2());
    

    Then you can loop through the list and Invoke each method.

    foreach(var method in actionList)
    {
        method.Invoke();
    }   
    

  • answered 2018-02-13 02:06 Dai

    I'm assuming randEvent is a List<EventHandler> or List<Action<Int32>>.

    Use Delegate.Invoke( args ) (as EventHandler and Action<T> are both Delegate sub-types).

    randEvent[0].Invoke( 123 );
    

    In C#, you can use () on a Delegate directly too:

    randEvent[0]( 123 );
    

  • answered 2018-02-13 02:22 JamesFaix

    In C#/.NET, different method signatures have different delegate types that represent them. Action represents functions that take no arguments and return no value, like void Foo(). If the functions you want to represent take a float parameter and return nothing, you would need to use Action<float>. Functions with return values are represented with the Func family of types (Func<T>, Func<T1, T2>...).

    You can only put one kind of delegate in a List<T>, so you can't mix Actions and Action<float>s.

    To get an item out of a list in C#, use [n]. Like

    List<Action> actions = new List<Action>();
    actions.Add(Foo);
    Action a = actions[0];
    

    To invoke a delegate instance in C#, call the Invoke method on it, or just use () which is shorthand for calling Invoke. For Action, Invoke takes 0 parameters, for Action<T> it takes a single T parameter, etc.

    So for your whole example:

    List<Action> actions = new List<Action>();
    
    void Test()
    {
        actions.Add(PrintStuff);
        actions[0]();
        //or
        actions[0].Invoke();
        //or
        foreach (var a in actions) a();
    }
    
    void PrintStuff()
    {
        print("This is a test of the random event system");
    }