[.net 面向对象程序设计进阶] (6) Lamda表达式(二) 表达式树快速入门
[.net 面向对象程序设计进阶] (6) Lamda表达式(二) 表达式树快速入门
本节导读:
认识表达式树(Expression Tree),学习使用Lambda创建表达式树,解析表达式树。
学习表达式在程序设计中的优点:比如构造动态查询、动态构造表达式树完成未知对象属性访问,比反射的性能高出很多。我们可以说表达式树才是Lambda的精髓,是我们必须要熟练掌握并灵活运用的。
1.关于表达式树(Expression Tree)
表达式树以树形数据结构表示代码,其中每一个节点都是一种表达式,比如方法调用和 x < y 这样的二元运算等。
表达式树,对于刚接触的人来说,比较难以理解。那么什么是表达式树,通俗点来说,就是使用一种树形的数据结构来缓存表达式。
2.表达式树能帮我们做点什么?
上面我们说了表达式树是一种数据结构,那么为什么要把表达式定义成表达式树呢,转成一种数据结构,能帮我们做点什么?先明确了他能为我们带来什么,才有动力继续看下去。
说到他的作用,当然是非常有用的,我们在很多场景下都要使用他,当表达式变为一个表达式树的数据结构时,表达式就变为一个对象,你可以对表达式树中的对象元素(表达式的代码)进行编辑和运算。下面列举几种常用的:
- 通过修改表达式树能够动态修改可执行代码
- 在不同数据库中执行 LINQ 查询
- 创建动态查询。
- 完成类似反射访问未知对象属性,通过动态构造表达式树,生成委托。
3. 表达式树的创建
命名空间: System.Linq.Expressions
创建表达式树示例:
Expression<Func<int, int, bool>> expression = (num,num2)=> num < num2;
这个语句包含三个部分:
- 一个声明: Func<int, int, int> function
- 一个等号: =
- 一个lambda表达式: (num,num2)=> num < num2;
expression 就是一个类型为Expression<T>的表达式树,可以看出,他并非是一个可执行代码,而是一种表达式树的数据结构。
4. 表达式树结构的构成
Expression<Func<int, int, bool>> expression = (num,num2)=> num < num2;
通过监视我们定义好的表达式树,可以看到其构成 
下面我们对几个重要属性说明:
- Body: 得到表达式的主体。例:(num < num2) 其中,Body中又包含属性Left和Right 在上例中分别为num和num2
- Parameters: 得到lambda表达式的参数。 例 {num,num2}
- NodeType: 获取树的节点的ExpressionType。共45种不同值,包含所有表达式节点各种可能的类型。例如返回常量,例如返回参数,例如取两个值的小值(<),例如取两个值的大值(>),例如将值相加(+),等等。例:Lambda
- Type: 获取表达式的一个静态类型。 例:Func<int, int, bool>。
- ReturnType:这个是表达式的返回类型 例:bool
还有一些其他属性Name、CanReduce等,这些不是很常用。
5.解析表达式树
我们了解了表达式树结构的组成,解析表达式变得相当容易了,下面我们直接通过一个示例来完成对一个表达式树的解析:
//表达式树(Expression)
Expression<Func<int, int, bool>> expression = (x, y) => x!= && x==y+; BinaryExpression exr = expression.Body as BinaryExpression;
IReadOnlyList<ParameterExpression> param = expression.Parameters as IReadOnlyList<ParameterExpression>;
BinaryExpression left = exr.Left as BinaryExpression;
BinaryExpression right = exr.Right as BinaryExpression;
ExpressionType exrType = exr.NodeType; ParameterExpression leftLeft = left.Left as ParameterExpression;
ConstantExpression leftRight = left.Right as ConstantExpression;
ExpressionType leftType = left.NodeType; ParameterExpression rightLeft = right.Left as ParameterExpression;
BinaryExpression rightRight = right.Right as BinaryExpression;
ExpressionType rightType = right.NodeType; ParameterExpression rightRightLeft = rightRight.Left as ParameterExpression;
ExpressionType rightRightType = rightRight.NodeType;
ConstantExpression rightRightRight = rightRight.Right as ConstantExpression; Console.WriteLine(exr.ToString());
表达式树的解析,里面的元素无非就下面几种:
A.BinaryExpression 包含二元运算符的表达式
B.ParameterExpression命名的参数表达式 ,一般是一组参数集合IReadOnlyList<ParameterExpression>
C.ConstantExpression常量值的表达式
D.ExpressionType节点类型
对于上面示例的表达树结构,我用图例的方式展现如下:

对于上面的结构,我们可以按上面代码中的对象元素变量与之一一对应如下图: 
6 要点:
本节我们介绍了表达式树在.NET面向对象程序设计中的作用、表达式树的创建与解析,相信小伙伴们对表达式树这种结构比较了解了。
表达式树(Expression Tree)就是一种使用对象的方式来描述表达式。这也正是.NET一切皆是对象的思想体现。
下一节我们会介绍动态创建一个表达式树结构、会举列说明几种表达式树在.NET程序设计中的应用。
==============================================================================================
<如果对你有帮助,记得点一下推荐哦,如有有不明白或错误之处,请多交流>
<对本系列文章阅读有困难的朋友,请先看《.net 面向对象编程基础》>
<转载声明:技术需要共享精神,欢迎转载本博客中的文章,但请注明版权及URL>
.NET 技术交流群:467189533 
==============================================================================================
[.net 面向对象程序设计进阶] (6) Lamda表达式(二) 表达式树快速入门的更多相关文章
- [.net 面向对象程序设计进阶] (5) Lamda表达式(一) 创建委托
[.net 面向对象程序设计进阶] (5) Lamda表达式(一) 创建委托 本节导读: 通过学习Lambda表达式,学会创建委托和表达式目录树,深入了解Lambda的特性,让你的代码变的更加清晰. ...
- [.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用
[.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用 本节导读:讨论了表达式树的定义和解析之后,我们知道了表达式树就是并非可执行代码,而是将表达式对象化后的数据结构.是 ...
- [.net 面向对象程序设计进阶] (17) 多线程(Multithreading)(二) 利用多线程提高程序性能(中)
[.net 面向对象程序设计进阶] (17) 多线程(Multithreading)(二) 利用多线程提高程序性能(中) 本节要点: 上节介绍了多线程的基本使用方法和基本应用示例,本节深入介绍.NET ...
- [.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能
[.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能 本节导读: 上节说了缓存是以空间来换取时间的技术,介绍了客户端缓存和两种常用服务器缓布,本节主要介绍一种. ...
- [.net 面向对象程序设计进阶] (1) 开篇
[.net 面向对象程序设计进阶] (1) 开篇 上一系列文章<.net 面向对象编程基础>写完后,很多小伙伴们希望我有时间再写一点进阶的文章,于是有了这个系列文章.这一系列的文章中, 对 ...
- [.net 面向对象程序设计进阶] (16) 多线程(Multithreading)(一) 利用多线程提高程序性能(上)
[.net 面向对象程序设计进阶] (16) 多线程(Multithreading)(一) 利用多线程提高程序性能(上) 本节导读: 随着硬件和网络的高速发展,为多线程(Multithreading) ...
- [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦
[.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦 本节导读:上篇文章简单介绍了.NET面向对象中一个重要的技术反射的基本应用,它可以让我们动态的调 ...
- [.net 面向对象程序设计进阶] (18) 多线程(Multithreading)(三) 利用多线程提高程序性能(下)
[.net 面向对象程序设计进阶] (18) 多线程(Multithreading)(二) 利用多线程提高程序性能(下) 本节导读: 上节说了线程同步中使用线程锁和线程通知的方式来处理资源共享问题,这 ...
- [.net 面向对象程序设计进阶] (3) 正则表达式 (二) 高级应用
[.net 面向对象程序设计进阶] (2) 正则表达式 (二) 高级应用 上一节我们说到了C#使用正则表达式的几种方法(Replace,Match,Matches,IsMatch,Split等),还 ...
随机推荐
- jQuery常用的插件及功能汇总-持续
1.图片轮播 jquery.soChange.js 2.滚动展示 MSClass.js 3.md5加密 md5.js 4.cookie操作 cookie.js 5.
- php特性包括哪些?
PHP的特性包括: 1. PHP 独特的语法混合了 C.Java.Perl 以及 PHP 自创新的语法. 2. PHP可以比CGI或者Perl更快速的执行动态网页——动态页面方面,与其他的编程语言相比 ...
- ready与onload区别一
<!DOCTYPE html><html> <head> <title>ready与onload区别一</title> <meta c ...
- PostMan插件安装
一直没装上postman,今天运气好,竟装上了 给大家show一下吧,也希望大家跟我一样走弯路甚至于走不过去!:) 1.下载Postman_v4.1.3.rar,这个是我测试验证并打包的: 加QQ群: ...
- C++builder中使用TScrollBox 以后,让scrollBox相应鼠标的上下滑动
1.在窗口的事件里搜索 mouseWheel的方法 2.在.cpp文件里实现下面的代码 void __fastcall TForm1::mouseWheel(TObject *Sender, TShi ...
- lvs DR模式下vip的端口无法telnet
错误介绍: 在lvs配置文件中新添加一个vip ,并添加一个virtual_server,添加两个realserver,配置文件都是复制,结果证明没问题,当时的效果是vip的端口telnet不了 过 ...
- eclipse/myeclipse sublime 实时更新文件改变
情形: 在使用eclipse/myeclipse开发的时候, 像JS 或者HTML 以及一些操作时,sublime 的效率比eclipse/myeclipse要快,所以我们就可以使用这两者一起开发. ...
- 那年有关 return ; 的一切
现在只知道在dev C++里面声明了函数的返回类型不为void就不能写return; ,但是如果返回值为void就可以写return; ,而且如你所愿.
- IIS服务的命令行方式重启命令
打开IIS配置窗口的CMD命令:开始---运行---CMD----输入inetmgr 直接使用CMD我们可以操作很多事情,比如启动IIS,重启IIS,停止IIS 重启IIS服务器,开始->运行- ...
- Windows Phone 8.1 新特性 - 控件之列表选择控件
本篇我们来介绍Windows Phone 8.1 新特性中的列表选择控件. 在Windows Phone 8 时代,大家都会使用 LongListSelector 来实现列表选择控件,对数据进行分组显 ...