调用由参数确定的C#中的方法
我有一个我希望调用的方法列表,每个方法都有一个按钮,还有一个处理按钮的通用方法 使用commandArgument如何运行所选方法调用由参数确定的C#中的方法,c#,asp.net,C#,Asp.net,我有一个我希望调用的方法列表,每个方法都有一个按钮,还有一个处理按钮的通用方法 使用commandArgument如何运行所选方法 例如,单击运行方法1按钮。在按钮的处理程序中,单击调用commandArgument中指定的方法如果您知道要调用的所有方法,并且数量不是很大,我将使用switch语句来调用它们。否则,您必须使用反射,例如,有关一些示例,请参见。那么CommandArgument中的字符串是否与方法的名称匹配?如果必须这样做,那么可以使用反射。我假设你基本上每个按钮都有一个按钮点击事
例如,单击运行方法1按钮。在按钮的处理程序中,单击调用commandArgument中指定的方法如果您知道要调用的所有方法,并且数量不是很大,我将使用switch语句来调用它们。否则,您必须使用反射,例如,有关一些示例,请参见。那么CommandArgument中的字符串是否与方法的名称匹配?如果必须这样做,那么可以使用反射。我假设你基本上每个按钮都有一个按钮点击事件,或者你不会问这个问题:
private void MethodA() { }
protected void Button_Click(object sender, EventArgs e)
{
string arg = ((Button)sender).CommandArgument; // = MethodA
MethodInfo method = this.GetType().GetMethod(arg);
method.Invoke(this, null);
}
虽然这看起来像一个巨大的代码气味。你为什么要这样做?为什么不能给每个按钮一个单独的事件处理程序,并直接调用每个方法
或者,为什么不在参数上使用switch语句:
protected void Button_Click(object sender, EventArgs e)
{
string arg = ((Button)sender).CommandArgument; // = MethodA
switch (arg)
{
case "MethodA":
MethodA(); break;
case "MethodB":
MethodB(); break;
}
}
为什么不实际使用这种命令模式呢
public interface ICommand
{
bool CanExecute(string command);
void Execute();
}
public class MethodACommand : ICommand
{
private MyForm form;
public MethodACommand(MyForm form) {... }
public bool CanExecute(string command) { return command.Equals("MethodA"); }
public void Execute() { form.MethodA(); }
}
public class CommandHandler
{
public CommandHandler(IEnumerable<ICommand> commandString) {...}
public Execute(string command)
{
foreach(var command in Commands)
{
if (command.CanExecute(commandString))
{
command.Execute();
break;
}
}
}
}
protected void Button_Click(object sender, EventArgs e)
{
string arg = ((Button)sender).CommandArgument; // = MethodA
commandHandler.Execute(arg);
}
公共接口ICommand
{
boolcanexecute(字符串命令);
void Execute();
}
公共类方法命令:ICommand
{
私人MyForm;
公共方法命令(MyForm格式){…}
public bool CanExecute(string命令){return command.Equals(“MethodA”);}
public void Execute(){form.MethodA();}
}
公共类命令处理程序
{
公共CommandHandler(IEnumerable commandString){…}
公共执行(字符串命令)
{
foreach(命令中的var命令)
{
if(command.CanExecute(commandString))
{
command.Execute();
打破
}
}
}
}
受保护的无效按钮\u单击(对象发送者,事件参数e)
{
字符串arg=((按钮)发送方).CommandArgument;/=MethodA
commandHandler.Execute(arg);
}
我喜欢伊恩的答案,但如果你想要不那么复杂的答案,你可以建立一个代表字典:
private IDictionary<string, Action> actions = new Dictionary<string, Action> {
{ "MethodA", MethodA },
{ "MethodB", MethodB }
};
当然,如果您知道参数的类型,可以修改它以接受参数。这假设MethodA和MethodB没有参数并返回void。Ahh。。。这是缓慢而危险的。。。最好改用委托。你真的应该考虑改变你的程序模式,为方法使用委托-这可能会被误用,特别是当使用字符串作为参数时..argh。。。为asp.net设置标记并吊销我的答案。您最好使用Button.Command事件,而不是Button.Click事件。您将获得一个CommandEventArgs参数,该参数同时包含CommandName和CommandArgument,因此不需要从按钮本身获取它们。()关于使用命令事件,您是对的,我刚才快速键入了这个命令,并修改了以前回答中的按钮单击调用代码。我知道,但我想让列表增长。我暂时只是使用switch case语句来设置它
protected void Button_Command( object sender, CommandEventArgs e )
{
if( actions.ContainsKey( e.CommandArgument ) )
actions[e.CommandArgument]();
else
throw new ArgumentException( "Cannot find action for key: "+ e.CommandArgument );
}