简体   繁体   English

使用数据中的参数调用C#方法

[英]Calling C# method with parameters from data

Say, I have an XML String like this, 说,我有一个像这样的XML字符串,

<METHOD>foo</METHOD>
<PARAM1>abc</PARAM1>
<PARAM2>def</PARAM2>
...
<PARAM99>ghi</PARAM99>
<PARAM100>jkl</PARAM100>

and I have a method 我有一个方法

void foo(String param1, String param2, ..., String param99, String param100)
{
...
}

Is there any easy way for me to map this string to a real method call with the params matching the param names of the method in C#? 有没有简单的方法让我将这个字符串映射到一个真正的方法调用,其中params匹配C#中方法的param名称?

Assuming you know the type, have an instance of it, and that the method is actually public: 假设您知道类型,拥有它的实例,并且该方法实际上是公共的:

string methodName = parent.Element("METHOD").Value;
MethodInfo method = type.GetMethod(methodName);

object[] arguments = (from p in method.GetParameters()
                      let arg = element.Element(p.Name)
                      where arg != null
                      select (object) arg.Value).ToArray();

// We ignore extra parameters in the XML, but we need all the right
// ones from the method
if (arguments.Length != method.GetParameters().Length)
{
    throw new ArgumentException("Parameters didn't match");
}

method.Invoke(instance, arguments);

Note that I'm doing case-sensitive name matching here, which wouldn't work with your sample. 请注意,我在这里进行区分大小写的名称匹配,这对您的示例无效。 If you want to be case-insensitive it's slightly harder, but still doable - personally I'd advise you to make the XML match the method if at all possible. 如果你想要不区分大小写,那就稍微困难了,但仍然可行 - 我个人建议你尽可能使XML与方法匹配。

(If it's non-public you need to provide some binding flags to the call to GetMethod .) (如果它是非公共的,则需要为GetMethod调用提供一些绑定标志。)

How about something like this: 这样的事情怎么样:

    public void Run(XmlElement rootElement)
    {
        Dictionary<string, string> xmlArgs = new Dictionary<string,string>(StringComparer.OrdinalIgnoreCase);
        foreach( XmlElement elem in rootElement )
            xmlArgs[elem.LocalName] = elem.InnerText;

        MethodInfo mi = this.GetType().GetMethod(xmlArgs["METHOD"]);

        List<object> args = new List<object>();
        foreach (ParameterInfo pi in mi.GetParameters())
            args.Add(xmlArgs[pi.Name]);

        mi.Invoke(this, args.ToArray());
    }

edit If you have to match the names in the constructor. 编辑如果必须匹配构造函数中的名称。 Just throw the constructor away, as it is not a list of name/values but just a list of required objecttypes, and names aren't necessary. 只需抛出构造函数,因为它不是名称/值的列表,而只是所需对象类型的列表,并且名称不是必需的。 Use properties to match between the xml element name and the field in the class. 使用属性在xml元素名称和类中的字段之间进行匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM