Вопрос по c#, reflection – Порядок параметра MethodInfo.Invoke

2

Я пытаюсь вызвать метод, используя отражение.

Что-то вроде этого:

method.Invoke(instance, propValues.ToArray())

Проблема состоит в том, что нет способа гарантировать, что массив параметров находится в правильном порядке. Есть ли способ указать, какие значения идут по какому параметру по имени? Или я действительно должен сделать пользовательский переплет? Если так, может кто-нибудь направить меня в правильном направлении?

Ваш Ответ

2   ответа
0

EDIT: Этот ответ фокусируется на типах параметров, а не на именах параметров. Если код запутан (или имеет разные имена параметров), тогда будет сложно отобразить решение, которое предоставил Джон Скит.

Во всяком случае, я много играл с этим .... Это то, что работает лучше всего для меня (не зная имен параметров):

    public object CallMethod(string method, params object[] args)
    {
        object result = null;

        // lines below answers your question, you must determine the types of 
        // your parameters so that the exact method is invoked. That is a must!
        Type[] types = new Type[args.Length];
        for (int i = 0; i < types.Length; i++)
        {
            if (args[i] != null)
                types[i] = args[i].GetType();
        }

        MethodInfo _method = this.GetType().GetMethod(method, types);

        if (_method != null)
        {
            try
            {
                _method.Invoke(this, args);
            }
            catch (Exception ex)
            {
                // instead of throwing exception, you can do some work to return your special return value

                throw ex;
            }
        }

        return result;

    }

Итак, вы можете вызвать вышеуказанную функцию:

    object o = CallMethod("MyMethodName", 10, "hello", 'a');

Вышеуказанный вызов должен иметь возможность вызывать этот метод с соответствующей подписью:

public int MyMethodName(int a, string b, char c) {
   return 1000;
}

Обратите внимание, что приведенный выше пример входит в объем & apos;this& APOS;

Вы все еще не поняли мою точку зрения: вы предполагаете, что проблема заключается в поиске правильного метода, но в вопросе нет ничего, что предполагало бы, что это так. Это все о порядке аргументов, и ваш ответ не поможет с этимat all.
Перечитав ваш ответ, я полагаю, что вы полностью упустили суть вопроса. В приведенном вами примере аргументы расположены в правильном порядке. Вся проблема ФП состоит в том, что аргументыaren't обязательно в правильном порядке. Он уже получил правильный метод, но он не знает, как передать аргументы, чтобы они соответствовали параметрам.
Хорошо, я объяснил, как методы могут быть вызваны на основе типов параметров. В вашем случае, если код запутан и у вас разные имена параметров, тогда невозможно будет сопоставить значения с точным параметром.
Даже если есть такие же типы, будет вызван правильный метод. Поверь мне, ты должен попробовать это.
Вы все равно будете сломаны, если есть несколько параметров одного типа ...
7

Is there a way to specific which values goes on which parameter by name?

Ну, вы указываете их в порядке параметров. Поэтому, если вы хотите сопоставить конкретные значения с конкретными именами, вы должны получить список параметров сmethod.GetParameters и сопоставить их таким образом. Например, если у вас былDictionary<string, object> с параметрами:

var arguments = method.GetParameters()
                      .Select(p => dictionary[p.Name])
                      .ToArray();
method.Invoke(instance, arguments);
@JonSkeet спасибо за быстрый отзыв. Не уверен, как я могу показать вам код, правильно отформатированный, кроме этого комментария: MethodInfo method = type.GetMethod (команда, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); Словарь & lt; строка, объект & gt; словарь = новый словарь & lt; строка, объект & gt; (); var parameters = method.GetParameters () .Select (p => словарь [p.Name]) .ToArray (); // в предыдущей строке я получаю исключение. Таким образом, я использовал ваш код в значительной степени, кроме объявления словаря, в котором я не был уверен.
Я не смогу использовать его из-за некоторых сложностей, связанных с ASP.NET MVC Framework. Тем не менее, это 100% ответили на вопрос. Спасибо! Pluc
Я попробовал этот подход, но продолжаю получать & quot; Данный ключ не присутствовал в словаре. & Quot; Что мне не хватает?
@Jacques: Ну, вы там создаете новый словарь, в котором нет никаких значений. Откуда вы ожидаете, что он получит значения? Если это не помогает, я предлагаю вам задать новый вопрос с кратким, но полным примером того, чего вы пытаетесь достичь.
@Jacques: Ну, это предполагает, что есть параметр, который вы не указали в своем словаре ...

Похожие вопросы