将命令映射到方法
本文关键字:方法 映射 命令 | 更新日期: 2023-09-27 18:24:23
我有一个命令行应用程序,在其中我使用一个字典将命令映射到方法,从一个字母的命令到方法的名称(作为字符串)。我可以使用这个方法来调用它,也可以告诉用户可用命令的列表,比如:
private static readonly Dictionary<string, string> commands =
new Dictionary<string, string>
{
{"u", "DestroyUniverse"},
{"g", "DestroyGalaxy"},
{"p", "DestroyPlanet"},
{"t", "TimeTravel"}
};
public void DestroyUniverse(Stack<string> argStack)
{
// destroy the universe according to the options in argStack
// ...
}
public void DestroyGalaxy(Stack<string> argStack)
{
// destroy the galaxy according to the options in argStack
// ...
}
// ... other command methods
public void Run(Stack<string> argStack)
{
var cmd = argStack.Next();
string methodName;
// if no command given, or command is not found, tell
// user the list of available commands
if (cmd == null || !commands.TryGetValue(cmd, out methodName))
{
Console.WriteLine("Available Commands:{0}{1}",
Environment.NewLine,
string.Join(Environment.NewLine,
commands.OrderBy(kv => kv.Key)
.Select(kv => string.Format("{0} - {1}", kv.Key, kv.Value))));
Environment.ExitCode = 1;
return;
}
// command is valid, call the method
GetType().GetMethod(methodName).Invoke(this, new object[] {argStack});
}
这很好,只是我不喜欢在字典中使用字符串作为值。因此,编译器不支持确保每个字符串都有一个方法。我宁愿以某种方式使用"方法",但对于列出命令的部分,我仍然可以访问方法的名称。有类似的东西吗?
为什么不起作用?
class Program
{
static void Main(string[] args)
{
var p = new Program();
p.Run(new Stack<string>(args.Reverse()));
Console.ReadKey();
}
private readonly Dictionary<string, Action<Stack<string>>> commands;
public Program() {
commands =
new Dictionary<string, Action<Stack<string>>>
{
{"u", DestroyUniverse },
{"g", DestroyGalaxy },
{"p", DestroyPlanet },
{"t", TimeTravel }
};
}
public void DestroyUniverse(Stack<string> argStack)
{
// destroy the universe according to the options in argStack
// ...
}
public void DestroyGalaxy(Stack<string> argStack)
{
// destroy the galaxy according to the options in argStack
// ...
}
private string Next(Stack<string argStack)
{
// wish this was a method of Stack<T>
return argStack.Any() ? argStack.Pop() : null;
}
public void Run(Stack<string> argStack)
{
var cmd = Next(argStack);
Action<Stack<string>> action = null;
// if no command given, or command is not found, tell
// user the list of available commands
if (cmd == null || !commands.TryGetValue(cmd, out action))
{
Console.WriteLine("Available Commands:{0}{1}",
Environment.NewLine,
string.Join(Environment.NewLine,
commands.OrderBy(kv => kv.Key)
.Select(kv => string.Format("{0} - {1}",
kv.Key, kv.Value.Method.Name))));
Environment.ExitCode = 1;
return;
}
// command is valid, call the method
action(argStack);
}
}
您可以使用反射。获取您感兴趣的所有方法的MethodInfo,并将它们放入字典中。稍后,您可以调用其中一个。如果您需要方法的名称作为字符串,您也可以从MethodInfo中获得它。