博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Expression Tree Introduction
阅读量:2235 次
发布时间:2019-05-09

本文共 2405 字,大约阅读时间需要 8 分钟。

表达式树听起来就是很神秘,很高端的东西,一直只听闻其酷炫,而未见其真容,今天了解了一下,有一些感悟,记录如下。

1.什么是表达式树

表达式树是将我们原来可以直接由代码编写的逻辑以表达式的方式存储在树状的结构里,从而可以在运行时去解析这个树,然后执行,实现动态的编辑和执行代码。

2.表达式树案例

1)最简单的表达式树

Expression
> 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
> 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
lambdaExpression = Expression.Lambda
(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
> myAction = Expression.Lambda
>(myBlock);Console.WriteLine(myAction.Compile()());Console.ReadKey();
3.总结

表达式树封装一些逻辑,在编译时运行,在实际开发时使用频率较低,主要是调试起来不是很方便,而且对于大多数不熟悉的人来说,看懂不是特别容易。作为.NET技术的一部分,了解下很有必要,毕竟技术都是触类旁通的。

你可能感兴趣的文章
一个框架解决几乎所有机器学习问题
查看>>
特征工程怎么做
查看>>
机器学习算法应用中常用技巧-1
查看>>
决策树的python实现
查看>>
了解 Sklearn 的数据集
查看>>
如何选择优化器 optimizer
查看>>
一文了解强化学习
查看>>
CART 分类与回归树
查看>>
seq2seq 的 keras 实现
查看>>
seq2seq 入门
查看>>
什么是 Dropout
查看>>
用 LSTM 做时间序列预测的一个小例子
查看>>
用 LSTM 来做一个分类小问题
查看>>
详解 LSTM
查看>>
按时间轴简述九大卷积神经网络
查看>>
详解循环神经网络(Recurrent Neural Network)
查看>>
为什么要用交叉验证
查看>>
用学习曲线 learning curve 来判别过拟合问题
查看>>
用验证曲线 validation curve 选择超参数
查看>>
用 Grid Search 对 SVM 进行调参
查看>>