Home > other >  Calling functions with different string names
Calling functions with different string names

Time:07-07

So I'm trying to make a 2D game (C#) where the player has different skills that they can use. The problem is that I don't know how to call a function with the string containing the skill name. There is always another way to do it, which is by making a really long list full of if-statements to check if the skill is named something, but this seems far from ideal.

Let's say a skill is called "Skill1". Is there any way to call a function called Skill1() by using the string "Skill1"? It would really help with making the code look good.

Thanks in advance

CodePudding user response:

What you're looking for are delegates (and more specifically a dictionary of delegates).

void Main()
{
    var things = new Dictionary<string, Action>
    {
        {"Thing1", DoThing1},
        {"Thing2", DoThing2},
        {"Thing3", DoThing3},
    };
    
    things["Thing1"]();
    things["Thing3"]();
    things["Thing2"]();
}


public void DoThing1()
{
    Console.WriteLine("In Do Thing 1");
}

public void DoThing2()
{
    Console.WriteLine("In Do Thing 2");
}

public void DoThing3()
{
    Console.WriteLine("In Do Thing 3");
}

For more information, search for Delegates, Actions and Funcs.

CodePudding user response:

Delegates are a good option but if you want to keep it simple you can use switch statement instead of if statements and it will be easy to maintain.

It's basic but maybe it will help

static void Main(string[] args)
        {
            Console.WriteLine("call skill");
            string _skill = Console.ReadLine();
            CallSkills(_skill);
        }

        public static void CallSkills(string skillname)
        {
            switch (skillname)
            {
                case "skill1":
                    //call skill1 method
                    break;
                case "skill2":
                    //call skill2 method
                    break;
                case "skill3":
                    //call skill3 method
                    break;
                case "skill4":
                    //call skill4 method
                    break;
                case "skill5":
                    //call skill5 method
                    break;
                default:
                    break;
            }
        }

CodePudding user response:

An alternative to using a dictionary with delegates is to using a switch expression with delegates.

One possible approach is to create a method that associates all relevant skill names with the appropriate Skill* method, as well as using the discard pattern (_ => ...; here: _ => null) to define a default value for any skillName that does not match any defined skill names in the expression:

private static Action GetSkillAction(string skillName)
{
    return skillName switch
    {
        "Skill1" => Skill1,
        "Skill2" => Skill2,
        _ => null
    };
}

To make it easier to use that method, you could create a method to actually perform a skill (by skill name). This method handles receiving a non-existing skill by only calling the associated action if the action is unlike null:

public static void PerformSkillAction(string skillName)
{
    var action = GetSkillAction(skillName);
    
    if (action != null)
    {
        action();
    }
}

Now, calling

PerformSkillAction("Skill1");

will result in a call to Skill1(), whereas calling

PerformSkillAction("Banana");

will not call anything.

Example fiddle here.

  • Related