低代码到底是不是行业毒瘤?一线大厂怎么做的?戳此了解>>> 了解详情
写点什么

掌握表达式树

2008 年 2 月 12 日

对于熟悉函数式编程语言的开发者而言,可能不需要再解释为什么说“表达式树(即 Expression Tree)是非常有用的”,但对其他人来讲,表达式树则是 C# 3.0 或 VB 9.0 的所有新特性中最引人注目的一个概念。

Charlie Calvert 讲解了表达式树的基础,他从语法描述开始,并以同 Visual Studio 2008 一起发行的示例程序——ExpressionTressVisualizer 为例,形象地展示了如何使用表达式树。

表达式树与 Lambda 表达式相关联,Lambda 表达式是可在行内实现预期代理和匿名代理的内容的一种方式。 Ian Griffiths 在他关于表达式树文章中,给出了一个非常不错的 Lambda 表达式介绍,以及 Lambda 与表达式树的关系。正如 Ian 所指出的,“Lambda 除了语法不同以外,并没有比我已掌握的匿名方法提供更多的东西,但是,它却使一些匿名方法无法实现的事情变成了可能。”

Func<int, bool> nonExprLambda = x => (x & 1) == 0;<br></br>Expression<Func<int, bool>> exprLambda = x => (x & 1) == 0;[…]

第二行更有趣,它变成 Func 的代理,将 Func 作为一种名为 Expression 的泛型的类型参数,然后按照相同的方式进行初始化,因此,你可能会认为两者是在完成同样的事情,但是,它却能让编译器知道了 Expression 类型,这就导致了不一样的行为;前者会直接将 Lambda 表达式编译为 IL,而后者则是通过对表达式进行评估后,生成一个可以创建并代表此表达式的对象树的 IL。

Charlie 仔细钻研了 Expression 的细节:

**Expression** 类共有四个属性:

  • Body:获取表达式的主体;
  • Parameters:获取 Lambda 表达示的参数;
  • NodeType:得到树中某些节点的表达式类型(ExpressionType),这是一个有 45 种不同值的枚举类型,代表表达式节点的所有可能类型,如返回常数、也可能返回参数、或者返回一个值是否小于另外一个(<),或者返回一个值是否大于另外一个(>),或者返回两个值的和(+)等等;
  • Type:得到表达式的静态类型,在本例中,表达式的类型是Func<int, int, int>。

在 C# 3.0 和 VB 9.0 大部分新特性中,表达式树在“LINQ,尤其是 LINQ to SQL”中扮演了一个非常重要的角色:

var query = from c in db.Customers<br></br> where c.City == "Nantes"<br></br>  select new { c.City, c.CompanyName };

LINQ 表达式会返回一个 IQueryable 类型的值,IQueryable 值包含有一个表达式树,由它来代表这个 LINQ 查询。当创建这个查询时,SQL 语句并没有被发送到数据库中,只有当你在代码中对这个 IQueryable 对象进行 Iterate 操作时,这个 SQL 语句才会被创建并执行,这个概念就是延迟执行

Charlie Calvert 对这种方法的使用进行了说明:

因为查询是以一种高度抽象的数据结构封装后传送给编译器的,所以,编译器可以以它期望的任一方式自由地进行翻译。查询的执行次序和途径并非强制指定的,相反,它可以对表达树进行分析,以发现你所期望的结果,然后再决定如何处理;至少在理论上,它可以独立地考虑很多因素,诸如当前的网络流量、数据库的负载、它当前已有的可用结果集等等;虽然在 LINQ to SQL 中,它实际上并没有去考虑所有这些因素,但在理论上它可以考虑更多它关心的因素;此外,它还可以对表达式树进行分析,并将 LINQ to SQL 的输出结果转换成截然不同的形式,然后传递给你手写的自定义代码。

Marlon Grech 展示了如何应用表达式树,以及如何创建表达式解析器。Octavio Hernández 提供了一个表达式树的表达式类层次汇总表。

查看英文原文 Get a Grasp on Expression Trees

2008 年 2 月 12 日 03:421888
用户头像

发布了 89 篇内容, 共 95359 次阅读, 收获喜欢 4 次。

关注

评论

发布
暂无评论
发现更多内容

Hash 一致性虚拟节点算法

李锦

第5周总结

娄江国

极客大学架构师训练营

架构师训练营第5周作业

时来运转

学习总结 -- Week 5

吴炳华

极客大学架构师训练营

第五周学习总结

刘卓

Week05总结

熊威

架构师训练营 第五周 基于虚拟节点的一致性Hash算法作业

且听且吟

极客大学架构师训练营

第五周学习总结

冯凯

week5 home work

东哥

一致性哈希

架构师训练营 - 命题作业 第 5 周

铁血杰克

架构师训练营-week5-作业

晓-Michelle

极客大学架构师训练营

架构师训练营第五章总结

吴吴

架构师训练营第5周总结

时来运转

陈芳,高考之后我要学计算机专业,将来干IT发财了,我就娶你!

张小方

面试 薪资 程序员求职 程序员买房 毕业

原来 JavaScript 中的 WeakMap 是这样子的

pingan8787

Java 前端 Web

一致性哈希算法

dony.zhang

一致性哈希

一致性 Hash Java 实现

陈皮

实现一致性hash算法

LEAF

一致性 hash 算法

changtai

极客大学架构师训练营

架构师训练营 - 学习总结 - 第五讲

吕浩

「架构师训练营」第五周作业

旭东(Frank)

算法 极客大学架构师训练营 哈希 一致性哈希

架构感悟5-算法之美

旭东(Frank)

架构 算法 感悟 极客大学架构师训练营

架构师训练营第五章作业

吴吴

「架构师训练营」Week5作业

Frank Zeng

MySQL分区表最佳实践

Simon

MySQL 数据库

阿里巴巴、百度、美团都在用的 Spring Cloud 微服务架构

java通天架构哪吒

Spring Cloud SpringCloud

基于领域驱动设计的业务中台架构设计

Winfield

中台 业务中台 领域驱动设计 DDD

计算机操作系统基础(十五)---使用fork系统调用创建进程

书旅

php laravel 操作系统 进程 线程’

架构师训练营Week 05 学习总结

Frank Zeng

第五周作业

刘卓

Week05作业

熊威

2021 ThoughtWorks 技术雷达峰会

2021 ThoughtWorks 技术雷达峰会

掌握表达式树-InfoQ