70053

System.Linq.Expressions:在运行时绑定LambdaExpression输入(S

考虑以下设置:

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)

这将是相当微不足道获得,因为它只是涉及将在现有的表达的顶部上的层。

Answer 1:

经过大量的搜索中我碰到魔术跌跌撞撞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)); } }

文章来源: System.Linq.Expressions: Binding LambdaExpression inputs at runtime

Recommend