Dynamic 动态构建lambda表达式

Dynamic 动态构建lambda表达式,dynamic,lambda,tree,expression,expression-trees,Dynamic,Lambda,Tree,Expression,Expression Trees,我知道如何构建一个简单的lambda,比如x=>x>5: int[] nbs = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; IEnumerable<int> result1 = nbs.Where(x => x > 5); ParameterExpression parameter = Expression.Parameter(typeof(int), "x"); ConstantExpression co

我知道如何构建一个简单的lambda,比如x=>x>5:

int[] nbs = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };            
IEnumerable<int> result1 = nbs.Where(x => x > 5);

ParameterExpression parameter = Expression.Parameter(typeof(int), "x");
ConstantExpression constant = Expression.Constant(5);
BinaryExpression expressionBody = Expression.GreaterThan(parameter, constant);
Expression<Func<int, bool>> expression = Expression.Lambda<Func<int, bool>>(expressionBody, parameter);
IEnumerable<int> result2 = nbs.Where(expression.Compile());

但是,如果能够动态地构造复杂的lambda,我仍然感兴趣

这段代码完成了这项工作

    ParameterExpression parameter = Expression.Parameter(typeof(Person), "p");
    ConstantExpression my_null_object = Expression.Constant(null);
    ConstantExpression gender = Expression.Constant("Gender");
    MethodCallExpression methodcall = Expression.Call(parameter, typeof(Person).GetMethod("FindAttribute"), gender);
    BinaryExpression is_null = Expression.Equal(methodcall, my_null_object);
    ConstantExpression constant = Expression.Constant("Female");
    MemberExpression member = Expression.Property(methodcall, typeof(Attribute).GetProperty("Value"));
    BinaryExpression expressionBody = Expression.Equal(member, constant);
    BinaryExpression cond = Expression.AndAlso(Expression.IsFalse(is_null), expressionBody);
这样可能更清楚

        ParameterExpression parameter = Expression.Parameter(typeof(Person), "p");

        ConstantExpression my_null_object = Expression.Constant(null);
        MethodCallExpression methodcall = Expression.Call(parameter, typeof(Person).GetMethod("FindAttribute"), Expression.Constant("Gender"));

        BinaryExpression cond = Expression.AndAlso(

            Expression.IsFalse(Expression.Equal(methodcall, my_null_object)),

            Expression.Equal(
                Expression.Property(methodcall, typeof(Attribute).GetProperty("Value")), 
                Expression.Constant("Female")
                )
        );

空条件运算符是一种语言功能。可以将其转换为以下代码:

var attribute = p.FindAttribute("Gender");
return attribute == null ? false : attribute.Value == "Female";
要构建表达式树,可以使用
expression.Block

var p = Expression.Parameter(typeof(Person), "p");
var findAttribute = Expression.Call(p,
    typeof(Person).GetMethod(nameof(Person.FindAttribute)),
    Expression.Constant("Gender"));


var attribute = Expression.Parameter(typeof(Attribute), "attribute");
var body = Expression.Block(
    new[] {attribute}, // local variables
    new Expression[]
    {
        Expression.Assign(attribute, findAttribute),
        Expression.Condition(
            Expression.Equal(attribute, Expression.Constant(null)),
            Expression.Constant(false),
            Expression.Equal(
                Expression.PropertyOrField(attribute, "Value"),
                Expression.Constant("Female")))
    }
);

var lambda = Expression.Lambda<Func<Person, bool>>(body, p);
var p=Expression.Parameter(typeof(Person),“p”);
var findAttribute=Expression.Call(p,
typeof(Person).GetMethod(nameof(Person.FindAttribute)),
表达式。常数(“性别”);
var attribute=Expression.Parameter(typeof(attribute),“attribute”);
var body=Expression.Block(
新[]{attribute},//局部变量
新表达式[]
{
Expression.Assign(属性,findAttribute),
表达式.条件(
Expression.Equal(属性,Expression.Constant(null)),
表达式。常量(false),
表达式。相等(
Expression.PropertyOrField(属性,“值”),
表达式。常量(“女性”))
}
);
var lambda=表达式lambda(body,p);
var attribute = p.FindAttribute("Gender");
return attribute == null ? false : attribute.Value == "Female";
var p = Expression.Parameter(typeof(Person), "p");
var findAttribute = Expression.Call(p,
    typeof(Person).GetMethod(nameof(Person.FindAttribute)),
    Expression.Constant("Gender"));


var attribute = Expression.Parameter(typeof(Attribute), "attribute");
var body = Expression.Block(
    new[] {attribute}, // local variables
    new Expression[]
    {
        Expression.Assign(attribute, findAttribute),
        Expression.Condition(
            Expression.Equal(attribute, Expression.Constant(null)),
            Expression.Constant(false),
            Expression.Equal(
                Expression.PropertyOrField(attribute, "Value"),
                Expression.Constant("Female")))
    }
);

var lambda = Expression.Lambda<Func<Person, bool>>(body, p);