重建表达式

时间:2015-08-14 09:31:48

标签: c# linq dynamic lambda expression

我的表达式如下:Expression<Func<TheObject, int, bool>> myExpression = (myObj, theType) => { myObj.Prop > theType };

我需要动态地将myExpression重建为类型为Expression<Func<TheObject, bool>>的新表达式,并将第一个表达式中的“theType”参数替换为具体值123,如:

Expression<Func<TheObject, bool>> myNewExpression = myObj => { myObj.Prop > 123 };

我该怎么做? BR 菲利普

1 个答案:

答案 0 :(得分:1)

使用简单的表达式替换器非常简单:

这是我为自己写的那个......支持简单的替换和多次替换。

using System;
using System.Collections.Generic;
using System.Linq.Expressions;

// A simple expression visitor to replace some nodes of an expression 
// with some other nodes. Can be used with anything, not only with
// ParameterExpression
public class SimpleExpressionReplacer : ExpressionVisitor
{
    public readonly Dictionary<Expression, Expression> Replaces;

    public SimpleExpressionReplacer(Expression from, Expression to)
    {
        Replaces = new Dictionary<Expression, Expression> { { from, to } };
    }

    public SimpleExpressionReplacer(Dictionary<Expression, Expression> replaces)
    {
        // Note that we should really clone from and to... But we will
        // ignore this!
        Replaces = replaces;
    }

    public SimpleExpressionReplacer(IEnumerable<Expression> from, IEnumerable<Expression> to)
    {
        Replaces = new Dictionary<Expression, Expression>();

        using (var enu1 = from.GetEnumerator())
        using (var enu2 = to.GetEnumerator())
        {
            while (true)
            {
                bool res1 = enu1.MoveNext();
                bool res2 = enu2.MoveNext();

                if (!res1 || !res2)
                {
                    if (!res1 && !res2)
                    {
                        break;
                    }

                    if (!res1)
                    {
                        throw new ArgumentException("from shorter");
                    }

                    throw new ArgumentException("to shorter");
                }

                Replaces.Add(enu1.Current, enu2.Current);
            }
        }
    }

    public override Expression Visit(Expression node)
    {
        Expression to;

        if (node != null && Replaces.TryGetValue(node, out to))
        {
            return base.Visit(to);
        }

        return base.Visit(node);
    }
}

你的TheObject

public class TheObject
{
    public int Prop { get; set; }
}

然后你只需要替换表达式主体中的第二个参数并重建Expression<>

public class Program
{
    public static void Main(string[] args)
    {
        Expression<Func<TheObject, int, bool>> myExpression = (myObj, theType) => myObj.Prop > theType;

        int value = 123;

        var body = myExpression.Body;

        var body2 = new SimpleExpressionReplacer(myExpression.Parameters[1], Expression.Constant(value)).Visit(body);

        Expression<Func<TheObject, bool>> myExpression2 = Expression.Lambda<Func<TheObject, bool>>(body2, myExpression.Parameters[0]);
    }
}