Search code examples
c#dictionaryconsole-applicationmorse-code

Access multiple methods stored in an Action[] dictionary


This question covers the use of actions in a dictionary. I want to do something similar, but with more than one method per action:

static readonly Dictionary<char, Action[]> morseDictionary = new Dictionary<char,Action[]>
        {
            { 'a', new Action[] {dot, dash} },
            { 'b', new Action[] {dash, dot, dot, dot} },
            { 'c', new Action[] {dash, dot, dash, dot} },
            { 'd', new Action[] {dash, dot, dot} },
            { 'e', new Action[] {dot} }
            // etc
        };

dot and dash refer to these private functions:

private static void dash(){
    Console.Beep(300, timeUnit*3);
}

private static void dot(){
    Console.Beep(300, timeUnit);
}

I have another function, morseThis, which is designed to convert a message string to audio output:

private static void morseThis(string message){
    char[] messageComponents = message.ToCharArray();
    if (morseDictionary.ContainsKey(messageComponents[i])){
        Action[] currentMorseArray = morseDictionary[messageComponents[i]];
        Console.WriteLine(currentMorseArray); // prints "System.Action[]"
    }       
}

In the example above, I am able to print "System.Action[]" to the console for every letter contained in the input message. However, my intention is to call the methods within currentMorseArray in order.

How do I access the methods contained within a given Action[] in my dictionary?


Solution

  • You're nearly there. You've got an array of actions, so now all you need to do is execute the actions in order.

    Actions and Funcs in C# are just like any other object - you can put them in arrays, assign them to variables, pass them to methods as arguments, and so on. The only difference is that you can call an action. The syntax for this looks just like the syntax for calling a method:

    Action myAction = ...
    myAction();  // call the action
    

    So to execute the actions in your array, you can just foreach down the array to pull them out one by one, and call each one in the body of the loop.

    private static void morseThis(string message)
    {
        char[] messageComponents = message.ToCharArray();
    
        if (morseDictionary.ContainsKey(messageComponents[i]))
        {
            Action[] currentMorseArray = morseDictionary[messageComponents[i]];
    
            foreach (Action action in currentMorseArray)
            {
                action();
            }
        }       
    }