Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
调用由参数确定的C#中的方法_C#_Asp.net - Fatal编程技术网

调用由参数确定的C#中的方法

调用由参数确定的C#中的方法,c#,asp.net,C#,Asp.net,我有一个我希望调用的方法列表,每个方法都有一个按钮,还有一个处理按钮的通用方法 使用commandArgument如何运行所选方法 例如,单击运行方法1按钮。在按钮的处理程序中,单击调用commandArgument中指定的方法如果您知道要调用的所有方法,并且数量不是很大,我将使用switch语句来调用它们。否则,您必须使用反射,例如,有关一些示例,请参见。那么CommandArgument中的字符串是否与方法的名称匹配?如果必须这样做,那么可以使用反射。我假设你基本上每个按钮都有一个按钮点击事

我有一个我希望调用的方法列表,每个方法都有一个按钮,还有一个处理按钮的通用方法

使用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 );
}