不能不说的C#特性-表达式树
最近发生了很多很多事情,频繁的搬家。工作上的事情也挺多的,所以博客更新的非常缓慢。
已经有很多很多人聊过这个话题,今天我在这里重复也不会探讨出什么新东西,只是把自己的理解描述出来,更是为了整个系列文章的完整性。
当你听说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#特性-表达式树相关推荐
- 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截...
程序猿修仙之路--数据结构之你是否真的懂数组? 数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构 .要想在之后的江湖历练中通关,数据结构必不可少.数据 ...
- 谈表达式树的缓存(7):五种缓存方式的总体分析及改进方案
终于到了这个系列的最后一篇文章了,这个系列的文章本是许多话题的基础,却拖了那么长时间还没有完结.这篇文章主要讨论五种缓存方式各自的优劣,以及他们的性能关键在什么地方,如果要进行改进又有什么可选方案.在 ...
- [.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用
[.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用 本节导读:讨论了表达式树的定义和解析之后,我们知道了表达式树就是并非可执行代码,而是将表达式对象化后的数据结构.是 ...
- IEnumerable和IQueryable的区别以及背后的ExpressionTree表达式树
关于IEnumerable和IQueryable的区别,这事还要从泛型委托Func<T>说起.来看一个简单的泛型委托例子: class Program { static void Main ...
- C# 快速高效率复制对象另一种方式 表达式树
1.需求 在代码中经常会遇到需要把对象复制一遍,或者把属性名相同的值复制一遍. 比如: public class Student{public int Id { get; set; }public s ...
- 只要十步,你就可以应用表达式树来优化动态调用
表达式树是 .net 中一系列非常好用的类型.在一些场景中使用表达式树可以获得更好的性能和更佳的扩展性.本篇我们将通过构建一个 "模型验证器" 来理解和应用表达式树在构建动态调用方 ...
- 再讲IQueryablelt;Tgt;,揭开表达式树的神秘面纱
接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...
- 【C#复习总结】细说表达式树
1 前言 系类1:细说委托 系类2:细说匿名方法 系列3:细说Lambda表达式 系列4:细说泛型委托 系列5:细说表达式树 系列6:细说事件 涛声依旧,再续前言,接着用大佬的文章作为开头. 表达式树 ...
- 不能不说的C#特性-迭代器(下),yield以及流的延迟计算
本系列文章连接: 不能不说的C#特性-对象集合初始化器 不能不说的C#特性-匿名类型与隐式类型局部变量 不能不说的C#特性-扩展方法 不能不说的C#特性-匿名方法和Lambda表达式 不能不说的C# ...
最新文章
- 「图解」ThreadLocal 在并发问题中的应用
- java知识点--基础篇(5)
- UglifyJs Unexpected token: keyword (const)
- TJU Problem 2857 Digit Sorting
- 在计算机中 用户程序,在用户计算机上的万维网客户程序是()
- 我的第一个REST客户端程序!
- 工作392-选择Hbuilder x导入项目
- python 绘制时频图 plt.specgram
- android 判断两个整数,【tips】判断两个整数是否是同一个数量级
- 速成pytorch学习——6天Dataset和DataLoader
- linux 链表头文件,Linux下单链表的实现
- HDU1290 重建希望小学【递推+打表】
- 银河麒麟服务器无raid驱动安装处理
- 阿里巴巴Java编程规范考试
- linux打包根目录
- 如何撤回 Gmail 已发送的邮件
- 最近k8s遇到的一些问题
- uboot环境下mmc操作_uboot mmc命令详解
- win10 删除删除账户,新的账户中文件资源管理器图标变白 找回方法
- 使用FFmpeg4android 实现视频 水印 剪切 压缩 旋转
热门文章
- ueditor滚动条
- clickinrefresh.php,IDCZE_v3.0 IDCZE商业导航系统全新仿照114la网址导航 - 下载 - 搜珍网...
- 【PAT】2021年冬季考试甲级,摸鱼游记、92分
- 【服务器】Cloudreve绑定七牛云免费对象存储
- Oracle→表、表字段数据类型、表DDL语句、数据DML语句、约束、case...when、decode
- SQL Server 删除数据表数据
- 多校 HDU 6313 Hack It——构造
- C++ 最大堆最小堆与push_heap pop_heap
- bzoj 1663: [Usaco2006 Open]赶集(最长路)
- bzoj 3749: [POI2015]Łasuchy