expressions:在运行时绑定LambdaExpression输入

本文关键字:LambdaExpression 输入 绑定 运行时 expressions | 更新日期: 2023-09-27 17:51:06

考虑以下设置:

class A { public int x; }
class B { public int y; }
static class Helper
{
    public static Expression<Func<B>> BindInput(
        Expression<Func<A, B>> expression,
        A input)
    {
        //TODO
    }
}
static void Main(string[] args)
{
    Expression<Func<B>> e = Helper.BindInput(
        (A a) => new B { y = a.x + 3 },
        new A { x = 4 });
    Func<B> f = e.Compile();
    Debug.Assert(f().y == 7);
}

我想在方法BindInput中做的是将表达式转换为将input嵌入其中。在Main的示例用法中,结果表达式e将是

() => new B { y = input.x + 3 }

其中input是传递给BindInput的第二个值。

我该怎么做呢?

编辑:

我应该补充说,下面的表达式e不是我正在寻找的:

((A a) => new B { y = a.x + 3 })(input)

这是相当容易获得的,因为它只涉及在现有表达式的顶部添加一层。

expressions:在运行时绑定LambdaExpression输入

经过大量的搜索,我偶然发现了神奇的ExpressionVisitor类。下面的代码似乎运行得很好:

class MyExpressionVisitor : ExpressionVisitor
{
    public ParameterExpression TargetParameterExpression { get; private set; }
    public object TargetParameterValue { get; private set; }
    public MyExpressionVisitor(ParameterExpression targetParameterExpression, object targetParameterValue)
    {
        this.TargetParameterExpression = targetParameterExpression;
        this.TargetParameterValue = targetParameterValue;
    }
    protected override Expression VisitParameter(ParameterExpression node)
    {
        if (node == TargetParameterExpression)
            return Expression.Constant(TargetParameterValue);
        return base.VisitParameter(node);
    }
}
static class Helper
{
    public static Expression<Func<B>> BindInput(Expression<Func<A, B>> expression, A input)
    {
        var parameter = expression.Parameters.Single();
        var visitor = new MyExpressionVisitor(parameter, input);
        return Expression.Lambda<Func<B>>(visitor.Visit(expression.Body));
    }
}
相关文章:
  • 没有找到相关文章