-1

The most basic method would be through a switch statement:

switch(action)
{
    case "Action1":
        DoAction1();
        return;
    case "Action2":
        DoAction2();
        return;
    case "Action3":
        DoAction3();
        return;
}

This is not only very messy, but breaks the Open/Closed Principal by requiring the class be changed to add new functionality. It is possible to get around that by putting the switch statement in a virtual method, but it's still messy.

I know it's possible to achieve a similar effect using a delegate, but in my case, the strings are loaded from an external file, so that's not an option.

EDIT: Just to be clear, I don't mind if the answer requires manually "mapping" strings to methods, so long as new methods can be added without modifying the base class, and it doesn't produce code smells like the switch statement above does.

Zerbu
  • 555
  • 1
  • 5
  • 12
  • **System.Reflection** – L.B Jul 23 '17 at 22:33
  • If you need to map strings to methods and don't want to maintain the association, then yes, you will need reflection. You will still have the issue that if you rename your methods, the association will break. – Dave Cousineau Jul 23 '17 at 22:58

2 Answers2

0

You could use reflection to perform dynamic method invocation, assuming that your string matches the method name exactly:

Type _t = this.GetType();
MethodInfo _methodInfo = _t.GetMethod(method);
var result = _methodInfo.Invoke(this, new object[] {  });

In the above code, you're getting the type of the current class object and then getting the method. The method variable would be the name of the method you want to call. In the invocation, the object array are the parameters you need to pass to the invoked method.

I have an example gist on it here.

0

you could use reflection, but reflection is very open ended.... if you want to control the mapping then use something like

   public class Invoker
    {
        Dictionary<string, Action> _actions = new Dictionary<string, Action>();

        public void Do(string action)
        {
            if (_actions.ContainsKey(action)) _actions[action]();
            else
            {
                // no match 
            }
        }

        public void AddAction(string action, Action f)
        {
            _actions.Add(action, f);
        }
}

then can use

var invoker = new Invoker()
invoker.AddAction("Action1", DoAction1);
invoker.AddAction("Action2", DoAction2);

Another alternative is to use Attributes which would give a more controlled way of doing reflection using a mapping

Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
  • I'll just also add, that you mention a base class, but quite likely you don't need a type hierarchy, but you haven't given any details about that. But there's a strong possibility that you can configure what you want rather than create a inheritance structure – Keith Nicholas Jul 23 '17 at 23:24