2010-10-20 71 views
2

我只是在学习表达式树的早期过程中。用BinaryExpression解析表达式和

据我了解,有关它们的好处是,他们可以当它们被用作参数进行解析,所以例如:

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

但我怎么能解析表达式时,也确实是内?

也许我误解了这一切,但后来我看不到使用表达式的原因?我现在已经浏览了将近数百个网站,他们都试图解释表达式树是什么,他们都成功了,希望他们从来没有解释过用法是什么 - 除了简单的解释“表达式树没有编译....”

回答

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"; 

那么你可以看看,虽然已生成并看看有什么有表达式树。

+0

感谢你为这个......嗯,是的,我没有想象像扩展 公共静态布尔吧(这个富富,表达>表达式) { ... } 然后查看表达式树,计算false或true,然后返回。 我在正确的轨道上吗? – Janus007 2010-10-20 23:13:27

+0

我不知道为什么你需要一个表达式树。如果你打算做的只是返回结果,那么传递它自己的'Func'会更有意义。 – 2010-10-21 08:31:51

+0

我受到以下启发: \t NServiceBus.Configure.With()。Log4Net(a => a。YourProperty =“value”); 设置这样的属性:) – Janus007 2010-10-21 08:49:24

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") 

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

+0

谢谢你澄清这一点,这正是我所希望的:)它确实回答了我的最后一个问题。 – Janus007 2010-10-20 23:00:29