最近发生了很多很多事情,频繁的搬家。工作上的事情也挺多的,所以博客更新的非常缓慢。

已经有很多很多人聊过这个话题,今天我在这里重复也不会探讨出什么新东西,只是把自己的理解描述出来,更是为了整个系列文章的完整性。

当你听说Linq给你的承诺时,你怎么想的?Wow,我们可以以统一的方式操作各种各样的数据了。这就是我当时的想法。虽然人们在现实中总是喜欢差异,认为差异才能产生美,如果一切的一切都是一样的,这个世界将无比的单调,可是作为程序员的我们却对标准趋之若鹜,对差异嫉恶如仇。看同桌的你是不是正在为了Oracle和Sql Server两种数据库编写两套数据访问的类?

表达式树概念

Linq的承诺貌似Java那个梦想一样:Write Once,Run Anywhere。Java是怎么做到的?Sun等公司为我们在各种平台架构上实现了各自的虚拟机,Java的编译分为两个阶段,第一阶段将Java代码编译为字节码,在这个阶段不管在什么平台上,只要Java源代码一样生成的字节码是一致的,第二个阶段,也就是运行阶段,虚拟机会根据平台的不同生成不同的代码。就是通过将编译器分为前端和后端来实现这个梦想。

实际上LINQ也是这么做的,对各种数据的操作无非“增删查改”,但是具体做的时候关系数据库需要使用SQL来操作,而XML需要XPath来操作。我们如何将“增删查改”的语法做到一致,让我们用起来好像操作的数据只有一种?

答案是使用表达式树

表达式树仅仅是将表达式(这里特指Lambda表达式)用树状的数据结构来表示。相当于Java的字节码,至于如何去解析这个树的结构那就看你自己了,如何去解释这个表达式树。

看下面这个Lambda表达式:

username => username == “yuyi”

我们主要看表达式的主体:username == “yuyi”,如果我们是要对数据库进行操作,这将翻译为字段username中所有值为”yuyi”的行,如果操作的是XML那也许是查询名称为username,值为”yuyi”的attribute。表达式树承载的只是这样一个结构:

如何解释它这是你的事。

在C#中Expression<Function<string,bool>> IsTrue = username=>username==”yuyi”,就表示一个表达式树,这个语句在编译后就组成为一个树状的结构。

在编译原理中,我们知道编译器的前两个阶段主要做的是:词法分析、语法分析。在词法分析中编译器会从代码文件中读入一个个的字符,然后识别出其中的关键字、标识符、运算符、常量、字符串等。

比如上面的表达式就会识别出:

Username->标识符

==->运算符

“yuyi”->字符串

这些东西就叫做符号

然后以这些符号作为输入进行语法分析,语法分析会将这些符号组合成一个树,这个树我们称之为抽象语法树(AST),表达式树也是一种简单的AST。

(在VS2008带的例子中有个DynamicQuery的例子,这里有一个Dynamic.cs文件,这里就自己做表达式的解析,只不过解析的是用字符串形式的表达式,通过这个代码你可以看看表达式的解析过程,这里有一个ExpressionParser类,它就是负责表达式的词法解析的,该类里有一个Token的机构,这就是上面所说的符号,TokenId表示符号的类型

<"Samples"1033"CSharpSamples"LinqSamples"DynamicQuery>)

对于Lambda表达式,有两种编译方式,常规的:

Func<string,bool> IsTrue = username => username == “yuyi”;

这个时候编译器会将其编译为匿名方法,关于匿名方法的相关介绍可以参看我这篇文章。

编译成表达式树:

Expression<Func<string,bool>> IsTrue = username => username == “yuyi”;

这么细微的差别,C#这次却不真的编译这条语句,而是将其进行词法、语法分析,得到的是一个数据结构。

我们注意到表达式树还有一个Compile实例方法,它可以将表达式编译成匿名方法,也就是这个数据结构可以向匿名方法转变。

想想Linq to SQL,实际上它不就是C#作为源语言,SQL作为目标语言的一个编译过程么。形成表达式树(抽象语法树)后,就是代码生成了,只不过这个代码生成有的时候是生成代码,比如Linq to SQL,生成的是SQL语句,有的时候是生成的方法调用,比如Linq to XML,生成的是对XML文档的操作。

为什么一样的语句,有的时候是操作内存中的对象集合,有的时候是操作远程数据库?请查看我这篇文章。

关于表达式树更多细节内容,你可以查看TerryLee老大的这篇图文并茂的文章

转载于:https://www.cnblogs.com/yuyijq/archive/2008/09/18/1292941.html

不能不说的C#特性-表达式树相关推荐

  1. 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截...

    程序猿修仙之路--数据结构之你是否真的懂数组? 数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构  .要想在之后的江湖历练中通关,数据结构必不可少.数据 ...

  2. 谈表达式树的缓存(7):五种缓存方式的总体分析及改进方案

    终于到了这个系列的最后一篇文章了,这个系列的文章本是许多话题的基础,却拖了那么长时间还没有完结.这篇文章主要讨论五种缓存方式各自的优劣,以及他们的性能关键在什么地方,如果要进行改进又有什么可选方案.在 ...

  3. [.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用

    [.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用 本节导读:讨论了表达式树的定义和解析之后,我们知道了表达式树就是并非可执行代码,而是将表达式对象化后的数据结构.是 ...

  4. IEnumerable和IQueryable的区别以及背后的ExpressionTree表达式树

    关于IEnumerable和IQueryable的区别,这事还要从泛型委托Func<T>说起.来看一个简单的泛型委托例子: class Program { static void Main ...

  5. C# 快速高效率复制对象另一种方式 表达式树

    1.需求 在代码中经常会遇到需要把对象复制一遍,或者把属性名相同的值复制一遍. 比如: public class Student{public int Id { get; set; }public s ...

  6. 只要十步,你就可以应用表达式树来优化动态调用

    表达式树是 .net 中一系列非常好用的类型.在一些场景中使用表达式树可以获得更好的性能和更佳的扩展性.本篇我们将通过构建一个 "模型验证器" 来理解和应用表达式树在构建动态调用方 ...

  7. 再讲IQueryablelt;Tgt;,揭开表达式树的神秘面纱

    接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...

  8. 【C#复习总结】细说表达式树

    1 前言 系类1:细说委托 系类2:细说匿名方法 系列3:细说Lambda表达式 系列4:细说泛型委托 系列5:细说表达式树 系列6:细说事件 涛声依旧,再续前言,接着用大佬的文章作为开头. 表达式树 ...

  9. 不能不说的C#特性-迭代器(下),yield以及流的延迟计算

    本系列文章连接: 不能不说的C#特性-对象集合初始化器 不能不说的C#特性-匿名类型与隐式类型局部变量 不能不说的C#特性-扩展方法  不能不说的C#特性-匿名方法和Lambda表达式 不能不说的C# ...

最新文章

  1. 「图解」ThreadLocal 在并发问题中的应用
  2. java知识点--基础篇(5)
  3. UglifyJs Unexpected token: keyword (const)
  4. TJU Problem 2857 Digit Sorting
  5. 在计算机中 用户程序,在用户计算机上的万维网客户程序是()
  6. 我的第一个REST客户端程序!
  7. 工作392-选择Hbuilder x导入项目
  8. python 绘制时频图 plt.specgram
  9. android 判断两个整数,【tips】判断两个整数是否是同一个数量级
  10. 速成pytorch学习——6天Dataset和DataLoader
  11. linux 链表头文件,Linux下单链表的实现
  12. HDU1290 重建希望小学【递推+打表】
  13. 银河麒麟服务器无raid驱动安装处理
  14. 阿里巴巴Java编程规范考试
  15. linux打包根目录
  16. 如何撤回 Gmail 已发送的邮件
  17. 最近k8s遇到的一些问题
  18. uboot环境下mmc操作_uboot mmc命令详解
  19. win10 删除删除账户,新的账户中文件资源管理器图标变白 找回方法
  20. 使用FFmpeg4android 实现视频 水印 剪切 压缩 旋转

热门文章

  1. ueditor滚动条
  2. clickinrefresh.php,IDCZE_v3.0 IDCZE商业导航系统全新仿照114la网址导航 - 下载 - 搜珍网...
  3. 【PAT】2021年冬季考试甲级,摸鱼游记、92分
  4. 【服务器】Cloudreve绑定七牛云免费对象存储
  5. Oracle→表、表字段数据类型、表DDL语句、数据DML语句、约束、case...when、decode
  6. SQL Server 删除数据表数据
  7. 多校 HDU 6313 Hack It——构造
  8. C++ 最大堆最小堆与push_heap pop_heap
  9. bzoj 1663: [Usaco2006 Open]赶集(最长路)
  10. bzoj 3749: [POI2015]Łasuchy