使用反射执行一个方法,参数在GetParameters中引发Exception

时间:2014-07-10 15:05:44

标签: c# reflection

我有一个控制台应用程序,我正在测试输入命令的基本功能,例如: 的修改

AddUser id=1 name=John surname=Doe

修改 假设方法AddUser可能如下所示:

public AddUser(int id, string name, string surname
{
    //add code here to add user
}

这是我的代码:

protected void Process(string command)
{
    //get the type
    Type type = this.GetType(); 

    //do a split on the command entered
    var commandStructure = command.Split(' ');

    try
    {
        //reassign the command as only the method name
        command = commandStructure[0];

        //remove the command from the structure
        commandStructure = commandStructure.Where(s => s != command).ToArray();

        //get the method
        MethodInfo method = type.GetMethod(command, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);

        //if the method was found
        if (method != null)
        {
            Dictionary<string, ParameterInfo> dictionary = new Dictionary<string, ParameterInfo>();

            //**Here's where I get the exception that the key was not found in the** 
            //**dictionary**
            var parameters = method.GetParameters()
                .Select(p => dictionary[p.Name])
                .ToArray();

            //add code here to apply values found in the command to parameters found
            //in the command
            //...

            method.Invoke(this, parameters);
        }
        else
        {
            throw new Exception("No such command exists man! Try again.");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        Prompt();
        Wait();
    }
}

I was trying to understand the stack answer provided by Jon Skeet但无法让它发挥作用。我认为这是因为我误解了他的例子的讨论或使用。

所以我的问题是:如何在命令提示符下获取用户输入的值填充的参数列表?方法部分工作,我成功运行没有参数的方法,但是当我添加代码来处理参数时,它变得复杂了。

2 个答案:

答案 0 :(得分:1)

我认为你要做的是获取一个你可以使用的参数字典,如果你的初始字符串包含一个逗号分隔的参数列表,你可以通过做这样的事情得到它

Dictionary<string, string> dictionary = commandStructure[1].Split(',')
.ToDictionary(x => x.Split('=').First(), x => x.Split('=').Last());

但请注意,这里的字典值是&#34;字符串&#34;,因为输入是以字符串形式出现的。

这将采取诸如

之类的输入
"GetUser id=1,name=tom,path=C"

并使用键&#34; id&#34;,&#34; name&#34;将其转换为字典。和&#34;路径&#34;,以及&#34; 1&#34;,&#34; tom&#34;和&#34; C&#34;。然后当你做

var parameters = method.GetParameters()
            .Select(p => dictionary[p.Name])
            .ToArray();

您将获得所需值的数组,可以将其传递给method.Invoke();

另外:如果你的原始参数列表是用空格分隔的,那么你的原始参数列表就是#34; Split&#34;语句将拆分这些,所以现在你的commandStructure数组将包含方法名称和参数。字典方法将成为:

Dictionary<string, string> dictionary = commandStructure.Skip(1)
.ToDictionary(x => x.Split('=').First(), x => x.Split('=').Last());

答案 1 :(得分:0)

你可能想要这个:

dictionary = method.GetParameters()
                   .ToDictionary(x => x.Name, x => x);

取代例外。但不确定为什么需要它。