Expression Tree Introduction
2015-09-04 00:35
316 查看
表达式树听起来就是很神秘,很高端的东西,一直只听闻其酷炫,而未见其真容,今天了解了一下,有一些感悟,记录如下。
1.什么是表达式树
表达式树是将我们原来可以直接由代码编写的逻辑以表达式的方式存储在树状的结构里,从而可以在运行时去解析这个树,然后执行,实现动态的编辑和执行代码。
2.表达式树案例
1)最简单的表达式树
这里Compile方法返回的是一个Fun<int,int>委托,从表达式树的定义上我们可以看到,表达式树只是在Fun<int,int>外面包了一层Expression,这样我们就能够更好地理解表达式树的实质含义了。
Dynamic方法的作用自然是调用逻辑了,这里需要注意的是,在API中提到的late-bound,这个意思也就是说,如果这个委托绑定过多个方法,那么DynamicInvoke调用的将是最后一次绑定的那个方法。
表达式树有三个重要的要素,那就是Body,ReturnType 和 Parameters
2)稍微复杂的表达式树
BlockExpression是一个语句块对象,最后通过Expression.Lambda<Action>(block)行程LamdaExpression,最终调用。
3)基本算术方法
表达式树封装了一些基本的计算。
3.总结
表达式树封装一些逻辑,在编译时运行,在实际开发时使用频率较低,主要是调试起来不是很方便,而且对于大多数不熟悉的人来说,看懂不是特别容易。作为.NET技术的一部分,了解下很有必要,毕竟技术都是触类旁通的。
1.什么是表达式树
表达式树是将我们原来可以直接由代码编写的逻辑以表达式的方式存储在树状的结构里,从而可以在运行时去解析这个树,然后执行,实现动态的编辑和执行代码。
2.表达式树案例
1)最简单的表达式树
Expression<Func<int, int>> exp = x => x + 1;这就是最简单的一个表达式树,仅仅包含一个lamda表达式。上面我们提到表达式树是多个代码逻辑的组合,只不过在运行时编译。那我们如何使用这个表达式树呢?
Console.WriteLine(exp.Compile().DynamicInvoke(4));我们看看上面这句话,Compile方法意思是编译这个表达式树,然后调用DynamicInvoke方法去调用,这个和我们上面所说的动态编译执行是一致的。
这里Compile方法返回的是一个Fun<int,int>委托,从表达式树的定义上我们可以看到,表达式树只是在Fun<int,int>外面包了一层Expression,这样我们就能够更好地理解表达式树的实质含义了。
Dynamic方法的作用自然是调用逻辑了,这里需要注意的是,在API中提到的late-bound,这个意思也就是说,如果这个委托绑定过多个方法,那么DynamicInvoke调用的将是最后一次绑定的那个方法。
表达式树有三个重要的要素,那就是Body,ReturnType 和 Parameters
Expression<Func<int, int>> exp = x => x + 1; var lambdaExpr = exp as LambdaExpression; Console.WriteLine(lambdaExpr.Body); Console.WriteLine(lambdaExpr.ReturnType.ToString()); foreach (var parameter in lambdaExpr.Parameters) { Console.WriteLine("Name:{0}, Type:{1}, ", parameter.Name, parameter.Type.ToString()); }
2)稍微复杂的表达式树
LoopExpression loopExpression = Expression.Loop( Expression.Call( null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }), Expression.Constant("Expression")) ); BlockExpression block = Expression.Block(loopExpression); Expression<Action> lambdaExpression = Expression.Lambda<Action>(block); lambdaExpression.Compile().Invoke();上面的语句创建了一个循环(loop)表达式,Expression.Call是循环的主体,调用Console.WriteLine方法,参数是Expression,Expression.Constant表示参数是一个固定值。
BlockExpression是一个语句块对象,最后通过Expression.Lambda<Action>(block)行程LamdaExpression,最终调用。
3)基本算术方法
表达式树封装了一些基本的计算。
ParameterExpression number = Expression.Parameter(typeof(int), "number"); BlockExpression myBlock = Expression.Block( new[] {number}, Expression.Assign(number, Expression.Constant(2)), Expression.AddAssign(number, Expression.Constant(6)), Expression.SubtractAssign(number,Expression.Constant(4)), Expression.MultiplyAssign(number, Expression.Constant(3)), Expression.DivideAssign(number, Expression.Constant(2)), Expression.ModuloAssign(number, Expression.Constant(5))); Expression<Func<int>> myAction = Expression.Lambda<Func<int>>(myBlock); Console.WriteLine(myAction.Compile()()); Console.ReadKey();
3.总结
表达式树封装一些逻辑,在编译时运行,在实际开发时使用频率较低,主要是调试起来不是很方便,而且对于大多数不熟悉的人来说,看懂不是特别容易。作为.NET技术的一部分,了解下很有必要,毕竟技术都是触类旁通的。
相关文章推荐
- Android 录音PCM 转G711U,非常简单,非FFMPEG
- [Search Engine] 搜索引擎技术之网络爬虫
- swift 学习<五> String
- 通过SQL语句直接实现Excel与数据库的导入导出
- hdu2049 不容易系列之(4)——考新郎
- 【POJ3020】【总数-最大二分匹配】【最小路径覆盖和点覆盖的区别是 路径的话要所有点覆盖了】
- 充满梦想的log4net探索之旅
- iOS 自定义Loading指示器
- Date和Calendar类的使用(一个例子)
- Flume - Too many unapproved licenses: 1
- Real Time Rendering 2.1 Architecture (体系结构)
- hdu 4915 Parenthese sequence(贪心,模拟)
- Flume - 安装及启动命令详解
- shell数组、循环实战演练
- 递归那些事儿
- 递归那些事儿
- dbms_stats
- USACO 1.3 Barn Repair
- 用Scrapy抓取豆瓣小组数据(二)
- mac下安装memcached