我如何计算引用参数的表达式的一部分?

问题描述 投票:0回答:1

我正在编写一种旨在解析方法调用表达式并确定(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,如果您想尝试一下或将其用作示例解决方案的基础。

c# expression
1个回答
0
投票

您需要将一组参数传递给Expression.Lambda<...>()调用-您应该能够使用与原始expression相同的参数集,因此将argumentLambda的定义更改为:

var argumentLambda = Expression.Lambda<Func<Input,string>>(argumentExpression, expression.Parameters);
© www.soinside.com 2019 - 2024. All rights reserved.