Вызов метода C # с параметрами из данных - PullRequest
3 голосов
/ 22 сентября 2009

Скажем, у меня есть такая XML-строка,

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

и у меня есть метод

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

Есть ли какой-нибудь простой способ сопоставить эту строку реальному вызову метода с параметрами, совпадающими с именами параметров метода в C #?

Ответы [ 3 ]

8 голосов
/ 22 сентября 2009

Предполагая, что вы знаете тип, имеете его экземпляр и метод на самом деле общедоступен:

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);

Обратите внимание, что здесь выполняется сопоставление имен с учетом регистра, которое не будет работать с вашим образцом. Если вы хотите не учитывать регистр, это немного сложнее, но все же выполнимо - лично я бы посоветовал вам сделать так, чтобы XML соответствовал методу, если это вообще возможно.

(Если это не публично, вам нужно предоставить некоторые флаги привязки для вызова GetMethod.)

2 голосов
/ 22 сентября 2009

Как насчет этого:

    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());
    }
0 голосов
/ 22 сентября 2009

edit Если вам нужно сопоставить имена в конструкторе. Просто выбросьте конструктор, так как это не список имен / значений, а просто список требуемых типов объектов, а имена не нужны. Используйте свойства для сопоставления имени элемента xml и поля в классе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...