System.Linq.Expressions:在运行时绑定LambdaExpression投入 [英] System.Linq.Expressions: Binding LambdaExpression inputs at runtime
问题描述
考虑以下设置:
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
是变换的表达有输入
嵌入到它。在主
的用法示例,结果表达式电子
将
What I want to do in the method BindInput
is transform the expression to have input
embedded into it. In the example usage in Main
, the resulting expression e
would be
() => new B { y = input.x + 3 }
其中,输入
是传递到 BindInput
第二个值。
我怎么会去这样做?
编辑:
我要补充一点,下面的表达式电子
为不可以我要找的:
I should add that the following expression e
is not what I'm looking for:
((A a) => new B { y = a.x + 3 })(input)
这将是相当琐碎获得,因为它只是涉及将在现有的表达之上的一层。
This would be fairly trivial to obtain because it just involves adding a layer on top of the existing expression.
推荐答案
在很多搜索我碰到魔术 ExpressionVisitor
类跌跌撞撞。下面似乎是完美的工作:
After lots of searching I stumbled across the magic ExpressionVisitor
class. The following seems to be working perfectly:
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:在运行时绑定LambdaExpression投入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!