System.Linq.Expressions:在运行时绑定LambdaExpression投入 [英] System.Linq.Expressions: Binding LambdaExpression inputs at runtime

查看:96
本文介绍了System.Linq.Expressions:在运行时绑定LambdaExpression投入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下设置:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆