Basically I\'m trying to make a string to function dictionary in c#, I\'ve seen it done like this:
Dictionary>
<
One way to address this issue is to introduce an argument container/command class that would contain the super set of function arguments, including the action type itself (the key from the dictionary in the above question):
public class ActionCommand
{
public ActionType ActionType { get; set; } // enum instead of string
public int Distance { get; set; }
public DirectionType DirectionType { get; set; }
// More properties as needed
}
Then, for each ActionType
implement a strategy class:
public interface IActionHandlerStrategy
{
bool AppliesTo(ActionCommand actionCommand);
string Apply(ActionCommand actionCommand);
}
public class WalkActionHandlerStrategy : IActionHandlerStrategy
{
public bool AppliesTo(ActionCommand actionCommand)
{
return ActionCommand.ActionType == ActionType.Walk;
}
public ActionResult Apply(ActionCommand actionCommand)
{
// Do something here and return the result of Walk action
return new ActionResult(...); // Container for results
}
}
public class JumpActionHandlerStrategy : IActionHandlerStrategy
{
public bool AppliesTo(ActionCommand actionCommand)
{
return ActionCommand.ActionType == ActionType.Jump;
}
public ActionResult Apply(ActionCommand actionCommand)
{
// Do something here and return the result of Jump action
return new ActionResult(...); // Container for results
}
}
Add more strategies as needed and implement a class that would apply them:
public class ActionHandler
{
// Register strategies with the handler; typically done with DI
protected IList<IActionHandlerStrategy> ActionHandlerStrategies = new List<IActionHandlerStrategy>
{
new JumpActionHandlerStrategy(),
new WalkActionHandlerStrategy(),
// More strategies here...
};
public ActionResult Handle(ActionCommand actionCommand)
{
var actionHandlerStrategy = ActionHandlerStrategies.FirstOrDefault(ahs => ahs.AppliesTo(actionCommand);
if (actionHandlerStrategy == null)
{
throw new Exception($"No strategy found for action type {actionCommand.ActionType}");
}
return actionHandlerStrategy.Apply(actionCommand);
}
}
The end result should allow for relatively simple addition of new actions without much impact on existing logic.
You can use Dictionary<string, Delegate>
. To call a function stored in a Delegate
, use the DynamicInvoke()
method.
I'd go with the ExpandoObject which was specifically meant to be able to have the CLR support dynamic languages (see IronPython, et al).
static void Main()
{
dynamic expando = new ExpandoObject();
expando.Do = new Func<string>(MyFunc);
expando.Do2 = new Func<string, string>(MyFunc2);
Console.WriteLine(expando.Do());
Console.WriteLine(expando.Do2("args"));
}
static string MyFunc()
{
return "Do some awesome stuff";
}
static string MyFunc2(string arg)
{
return "Do some awesome stuff with " + arg;
}