Getting the values of method parameters inside expression trees

.net c# expression-trees

Question

I'm messing around with expression trees, but I'm little stuck.

I have this expression:

Expression<Func<IX, int>> expr = i => i.GetAll(1, b, method());

Where :

int b = 2;

public static int method()
{
    return 3;
}

public interface IX
{
    int GetAll(int a, int b, int c);
}

Now I want to get name of the method and values of parameters for this method. Name of the method is easy, but parameter values are harder part. I know I can parse them myself, but I would need to handle all cases (ConstantExpression, MemberExpression, MethodCallExpression and maybe more I'm not aware of). So I was thinking if there was "general" way to get their values. eg 1, 2, 3.

Accepted Answer

You can get the arguments of the MethodCallExpression in question and create compiled Func<object>s from them (boxing value-types if necessary), which can then be evaluated.

E.g.:

var args = from arg in ((MethodCallExpression)expr.Body).Arguments
           let argAsObj = Expression.Convert(arg, typeof(object))
           select Expression.Lambda<Func<object>>(argAsObj, null)
                            .Compile()();

This will obviously blow up if the expression's body is not a method-call expression or if any of the arguments to the method cannot be evaluated as is (e.g. if they depend on the argument to the expression).

Obviously, you can do a better job if you know the types of the arguments to the method beforehand. For your specific example, this should work:

var args = from arg in ((MethodCallExpression)expr.Body).Arguments               
           select Expression.Lambda<Func<int>>(arg, null)
                            .Compile()();

Popular Answer

Can you not just get all the parameters and then compile and execute them? I don't see how it would be possible to get all the values without executing if they can be method calls.




Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why