用BinaryExpression解析表达式树

时间:2010-10-20 21:12:17

标签: c# functional-programming expression-trees

我刚刚学习表达树的早期过程。

据我了解,关于它们的好处是它们可以在用作参数时进行解析,例如:

Foo.Bar(x => x.Process == "On" && x.Name == "Goofy")

但是当里面有AND时我怎么解析表达式?

也许我误解了一切,但后来我看不出使用表情的原因?我现在看了几百个网站,这些网站都试图解释表达式树是什么,它们都成功了,期望它们从来没有解释过用途是什么 - 除了琐碎的解释“表达树没有编译......”

2 个答案:

答案 0 :(得分:1)

表达式以树的形式表示代码。树的每个节点代表代码的一部分。例如,你问题中lambda表达式主体的树是这样的:

BinaryExpression (AndAlso)
  .Left = BinaryExpression (Equal)
    .Left = MemberExpression (x.Process)
      .Expression = ParameterExpression (x)
      .Member = MemberInfo (Process)
    .Right = ConstantExpression ("On")
  .Right = BinaryExpression (Equal)
    .Left = MemberExpression (x.Name)
      .Expression = ParameterExpression (x)
      .Member = MemberInfo (Name)
    .Right = ConstantExpression ("Goofy")

通常,表达式所代表的代码不会被执行,甚至不会被编译:它被分析以从中提取一些信息,将其转换为另一个表达式,甚至生成完全不同的东西(如SQL查询中的Linq to SQL或Entity Framework)。编译代码是不可能的,因为没有办法对其进行分析(至少不容易)。

答案 1 :(得分:0)

我使用了表达式来构建一个简单的领域特定语言。这用于我工作的实际应用程序中,因此它不是玩具项目。

我基本上创建了一个流畅的界面,允许我构建Predicate<T>个委托,例如:

Predicate<MyClass> condition = (new ConditionBuilder()).GreaterThanConst(9)
                                                       .And()
                                                       .LessThanConst(4)
                                                       .ToPredicate();

每个方法都会将相关表达式添加到当前树中。比ToPredicate将表达式编译为委托。

GreaterThanConst方法类似于:

public ConditionBuilder GreaterThan(object constant)
{
    condition = Expression.GreaterThan(Expression.Parameter(constant.GetType()), Expression.Constant(constant));
    return this;
}

哪里condition是持有正在构建的树(成长?)的成员。

要解析表达式,您需要编写如下内容:

Expression<Func<YourClass, bool>> expr = x => x.Process == "On" && x.Name == "Goofy";

然后你可以查看生成的表达式树,看看那里有什么。