我希望能够很好地掌握这个主题,因此想向社区提出以下问题:
答案 0 :(得分:6)
表达树带来什么好处?
表达式树允许程序以简化的方式在运行时操作它自己的实现的一部分。它们允许表达式作为其结构的表示传递,而不仅仅是可以调用的委托。
这句话究竟是什么意思:“表达式树是编译为代码的数据”?
C#/ .NET之前的语言支持这种操作......最好的例子是LISP。在程序内的数据结构中表示程序结构的能力称为homoiconicity。 C#以表达式树的形式支持有限的同音性。 C#语言允许从代码中的(子集)表达式透明地创建表达式树。例如:
int x = 3;
Expression<Func<bool>> IsXLessThan4Expr = () => x < 4;
Func<bool> IsXLessThan4 = () => x < 4;
变量IsXLessThan4Expr
是从lambda表达式捕获的表达式树。如果我们想要了解它的结构是什么,我们现在可以遍历该表达式的表示 - 并且如果我们愿意,可以操纵它。相反,代表IsXLessThan4
无法检查......它只能被调用。当然,您可以始终获得任何方法的原始IL(假设您具有必要的权限) - 但是从IL转换程序的逻辑结构比从表达式树转换要困难得多。
.net解决了表达树和函数式编程的常见挑战?
使用表达式树来解决非平凡问题的最好例子是LINQ-to-SQL,其中IQueryable
的实现能够将用C#编写的查询表达式树转换为等价的SQL查询可以由数据库执行。
表达式树还可以动态生成C#代码 - 因为表达式树可以编译为lambdas。这是一个例子:
var paramNotification =
Expression.Parameter(typeof (NotificationEntry), "noti");
Func<NotificationEntry, bool> predicate =
m_PredicateExpr = Expression.Lambda<Func<NotificationEntry, bool>>(
Expression.LessThan(
Expression.Property(paramNotification, "Value"),
Expression.Constant(100)),
new[] {paramNotification})
.Compile();
上面的代码片段创建了一个表达式,用于将Value
对象的NotificationEntry
字段与某个提供的常量(100)进行比较 - 并将其编译为我们可以调用的lambda。
有什么好的在线资源可以加快这个问题的速度?
MSDN可能是你目前最好的选择。
答案 1 :(得分:5)
他们带来了获取源代码并在执行时“理解”它的能力 - LINQ提供商是此的主要目标
嗯,表达式树通常是从源代码构建的(例如转换后的lambda表达式),但不是将源代码编译成可执行文件形式,而是将其内置到树中,其他代码可以检查。 (更确切地说,编译器获取源代码,并发出可执行代码,然后在执行时构建表达式树。)
说实话,表达式树和函数式编程似乎与我正交。两者都经常处理更高阶的函数,但这就是它。