dimanche 9 juillet 2017

Invoking a MethodCallExpression with named parameter constants

Say I have some function like so

public string TestValue(string hello, Guid world)
{
    return hello + world;
}

Assuming that objectParams is a dictionary of object Dictionary<string, object> that map the parameter name to the value, I'm currently matching the parameter values to the method name like so:

var method = this.GetType().GetMethod("TestValue");
var methodParameters = method.GetParameters();
var paramMatcher = (from paramValue in objectParams
                    from methodParam in methodParameters
                    where param.Key == clrParam.Name
                    select (name: clrParam.Name,
                            type: clrParam.ParameterType,
                            value: paramValue.Value);

I then build the expression to call the method TestValue like so, but this is the part I'm having trouble with.

var paramExpress = (from param in paramMatcher
                    select Expression.Assign(Expression.Parameter(param.type, param.name), Expression.Constant(param.parsedValue)));

Func<object> result = Expression.Lambda<Func<object>(Expression.Call(Expression.Constant(this),
    method, paramExpress)).Compile();
var res = result.Invoke(); //should return 'somestring+xxxxxxx-xxxx...etc'

The issue is that I can't guarantee that the parameter values are in call order so I want to rely on the name of the parameters to call. I'm not sure on how to assign the constant values to their parameter expressions properly. Running this code results in the exception System.InvalidOperationException: 'variable 'hello' of type 'System.String' referenced from scope '', but it is not defined' when compiling the lambda.





Aucun commentaire:

Enregistrer un commentaire