我正在编写一种旨在解析方法调用表达式并确定(1)被调用的方法和(2)被传递的参数的方法。我可以很好地检索该方法,但无法评估参数表达式。
这里是代码:
public static void InspectExpression(Expression<Action<Input>> expression)
{
var memberExpression = expression.Body as MethodCallExpression;
var methodName = memberExpression.Method.Name;
Console.WriteLine("The expression calls the {0} method.", methodName);
var argumentExpression = memberExpression.Arguments[0];
var argumentLambda = Expression.Lambda<Func<string>>(argumentExpression);
var compiled = argumentLambda.Compile();
var argumentValue = compiled();
Console.WriteLine("The expression would pass {0} as the first argument to {1}", argumentValue, methodName);
}
我用以下代码称呼它:
public class Input
{
public string SomeProperty { get; set; }
}
public static void MethodName(string arg)
{
//Doesn't matter what this does
}
public static void Main()
{
InspectExpression( i => MethodName(i.SomeProperty) );
}
但是这会产生以下异常:
[System.InvalidOperationException: variable 'i' of type 'Input' referenced from scope '', but it is not defined]
这很有意义,因为在不知道输入值的情况下无法评估该表达式,因为参数是根据表达式的输入来计算的。
所以我尝试添加这样的输入:
public static void InspectExpression(Expression<Action<Input>> expression)
{
var memberExpression = expression.Body as MethodCallExpression;
var methodName = memberExpression.Method.Name;
Console.WriteLine("The expression calls the {0} method.", methodName);
var argumentExpression = memberExpression.Arguments[0];
var argumentLambda = Expression.Lambda<Func<Input,string>>(argumentExpression);
var compiled = argumentLambda.Compile();
var sampleInput = new Input { SomeProperty = "Hello world" };
var argumentValue = compiled(sampleInput);
Console.WriteLine("The expression would pass {0} as the first argument to {1}", argumentValue, methodName);
}
这引发了例外:
[System.ArgumentException: Incorrect number of parameters supplied for lambda declaration]
我猜我必须以某种方式向表达式添加参数引用,但我确实无所适从。
提供示例输入,如何检索此表达式的计算参数?
这里是link to a Fiddle,如果您想尝试一下或将其用作示例解决方案的基础。
您需要将一组参数传递给Expression.Lambda<...>()
调用-您应该能够使用与原始expression
相同的参数集,因此将argumentLambda
的定义更改为:
var argumentLambda = Expression.Lambda<Func<Input,string>>(argumentExpression, expression.Parameters);