5

We're currently using .NET 3.5 and part of our application uses dynamic invocation (using MethodBase.Invoke)

I am wondering if it is possible to mix in Named Parameters (in .NET 4) with dynamic invocation, to perform something similar to:

// Dictionary that holds parameter name --> object mapping
var parameters = new Dictionary<string, object>();

// Add parameters ....

// Invoke where each parameter will match the one from the method signature.
methodInfo.Invoke(obj, parameters);

Is there any API that allows this option out of the box? If not, is it possible to develop some solution to perform this?

EDIT:

Rethinking of this problem, it sounds similar to how the compiler may actually need to match method calls based on argument lists. Perhaps there's some Compiler API (or the new Roslyn project) that allows doing just this easily? (without coding it myself which may be prone to errors).

3 Answers 3

22

You can use code like this:

public static class ReflectionExtensions {

    public static object InvokeWithNamedParameters(this MethodBase self, object obj, IDictionary<string, object> namedParameters) { 
        return self.Invoke(obj, MapParameters(self, namedParameters));
    }

    public static object[] MapParameters(MethodBase method, IDictionary<string, object> namedParameters)
    {
        string[] paramNames = method.GetParameters().Select(p => p.Name).ToArray();
        object[] parameters = new object[paramNames.Length];
        for (int i = 0; i < parameters.Length; ++i) 
        {
            parameters[i] = Type.Missing;
        }
        foreach (var item in namedParameters)
        {
            var paramName = item.Key;
            var paramIndex = Array.IndexOf(paramNames, paramName);
            if (paramIndex >= 0)
            {
                parameters[paramIndex] = item.Value;
            }
        }
        return parameters;
    }
}

And then call it like this:

var parameters = new Dictionary<string, object>();
// Add parameters ...
methodInfo.InvokeWithNamedParameters(obj, parameters);
Sign up to request clarification or add additional context in comments.

8 Comments

What would happen if the method uses default parameter values (.NET 4 feature)? does this solution work in that case? (can it differentiate between a null passed parameter, to a parameter that should not be passed (and thus take the default value)? I am not sure, but i will take the code and test that!
@lysergic-acid: look here for some ideas.
awesome so basically i can amend your example to reflect for these attributes and get the default value into the array in any case. Thanks!
I've changed the code to initialize the parameters with Type.Missing to account for optional parameters. But I haven't tested it, please check that it works.
You might want to check if paramIndex != -1 before you set the value to prevent IndexOutOfRangeException.
|
1

you can get your paramter names with the help of this article How can you get the names of method parameters? and then you can reorder them to invoke them as described here Reflection: How to Invoke Method with parameters

Comments

1

With .net4, I have an opensource framework ImpromptuInterface (found in nuget) that makes it easy to use the DLR apis for late invocation including named/optional parameters.

var result = Impromptu.InvokeMember(target, "MyMethod", parameters.Select(pair=>  InvokeArg.Create(pair.Key, pair.Value)).Cast<object>().ToArray());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.