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.