MethodInfo.Invoke parameter order

2019-04-13 19:32发布

问题:

I'm trying to invoke a method using reflection.

Something like this:

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

The problem is that there isn't a way to ensure the array of parameters is in the right order. Is there a way to specific which values goes on which parameter by name? Or do I really have to make a custom binder? If so, can anyone guide me in the right direction?

回答1:

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

Well, you specify them in parameter order. So if you want to map specific values to specific names, you should fetch the parameter list with method.GetParameters and map them that way. For example, if you had a Dictionary<string, object> with the parameters:

var arguments = method.GetParameters()
                      .Select(p => dictionary[p.Name])
                      .ToArray();
method.Invoke(instance, arguments);


回答2:

EDIT: This answer focuses on parameter types not the parameter names. If the code is obfuscated (or having different param names) then it will be difficult to map the solution that Jon Skeet has provided.

Anyway, I had been playing with this a lot.... This is what works best for me (without knowing param names) :

    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;

    }

so, you can call the above function:

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

The above call will should be able to invoke this method with matching signature:

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

Please note that he above example is in the scope of 'this'



标签: c# reflection