表达式树(2)

从上面例子可以看到,当我们要经常使用一个操作的时候,我们最好创建一个委托实例,然后反复调用,而不是每次使用的时候都使用Lambda表达式(例如例子中的printer委托实例)。

相比C# 1.0中的委托或者C# 2.0的匿名函数,结合Lambda表达式,对List<T>中的数据操作变得简单,易读。

表达式树

表达式树也称表达式目录树,将代码以一种抽象的方式表示成一个对象树,树中每个节点本身都是一个表达式。表达式树不是可执行代码,它是一种数据结构。

下面我们看看怎么通过C#代码建立一个表达式树。

构建表达式树

System.Linq.Expressions命名空间中包含了代表表达式的各个类,所有类都从Expression派生,我们可以通过这些类中的静态方法来创建表达式类的实例。Expression类包括两个重要属性:

Type属性代表求值表达式的.NET类型,可以把它视为一个返回类型

NodeType属性返回所代表的表达式的类型

下面看一个构建表达式树的简单例子:

Expression numA = Expression.Constant(6); Console.WriteLine("NodeType: {0}, Type: {1}", numA.NodeType, numA.Type); Expression numB = Expression.Constant(3); Console.WriteLine("NodeType: {0}, Type: {1}", numB.NodeType, numB.Type); BinaryExpression add = Expression.Add(numA, numB); Console.WriteLine("NodeType: {0}, Type: {1}", add.NodeType, add.Type); Console.WriteLine(add); Console.Read();

代码的输出为:

表达式树

通过例子可以看到,我们构建了一个(6+3)的表达式树,并且查看了各个节点的Type和NodeType属性。

Expression有很多派生类,有很多节点类型。例如,BinaryExpression就代表了具有两个操作树的任意操作。这正是NodeType属性重要的地方,它能区分由相同的类表示的不同种类的表达式。其他的节点类型就不介绍了,有兴趣可以参考MSDN。

对于上面的例子,可以用下图描述生成的表达式树,值得注意的是,"叶子"表达式在代码中是最先创建的,,表达式是自下而上构建的。表达式是不易变的,所有可以缓存和重用表达式。

表达式树

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/cec5f5d4b02d3e171ee2002e4b687d72.html