数据结构论坛

首页 » 分类 » 问答 » C表达式树及其应用Express
TUhjnbcbe - 2021/3/1 18:20:00

目的:

什么是表达式树?表达式能用来做什么?

一、什么是表达式树

官方解释:中文:提供一种基类,表示表达式树节点的类派生自该基类。它还包含用来创建各种节点类型的static(在VisualBasic中为Shared)工厂方法。这是一个abstract类。英文:Providesthebaseclassfromwhichtheclassesthatrepresentexpressiontreenodesarederived.Italsocontainsstatic(SharedinVisualBasic)factorymethodstocreatethevariousnodetypes.Thisisanabstractclass.

在c#中,我们可以定义一种树状的数据结构来描述c#中的代码,这种树状的数据结构就是表达式树,也称之为表达式(各种表达式之间是可以相互嵌套的)。比如说:(5-2)+(2+3)这个表达式,拆分成树状结构如下图:

表达式树在c#中,微软为每种运算类型的代码定义了不同的表达式类型,它们有共同的基类:Expression。

表达式树基类Expression(抽象类)

表达式Expression说明:它表示所有出现在c#中的代码的类型,主要包含两个属性:NodeType和Type.关于这两个属性定义如下:

1.NodeType类型为[ExpressionType]:这个表达式的节点类型,这是一个枚举,c#中定义了85个节点类型

ExpressionType

2.Type:这个表达式的静态类型,也就是这个表达式的返回类型

Type二、表达式能用来做什么?

表达式树的创建有Lambda法和组装法。学习表达式树需要委托、Lambda、Func基础。系统在底层会自动把Lambda表达式转为表达式树。

表达式树可以结合数据库查询或Linq,衍生很多高级操作。例如动态查询、遍历表达式树、转成成SQLwhere子句等等,

示例1

下面的代码示例演示如何创建块表达式。块表达式包含两个[MethodCallExpression]对象和一个[ConstantExpression]对象。

usingSystem.Linq.Expressions;BlockExpressionblockExpr=Expression.Block(Expression.Call(null,typeof(Console).GetMethod("Write",newType[]{typeof(String)})!,Expression.Constant("Hello")),Expression.Call(null,typeof(Console).GetMethod("WriteLine",newType[]{typeof(String)})!,Expression.Constant("World!")),Expression.Constant(42));foreach(varelementinblockExpr.Expressions){element.ToString().Dump();//此处会循环输出://Write("Hello")//WriteLine("World!")//42}varexpr=Expression.LambdaFuncint(blockExpr).Compile();expr.ToString().Dump();//此处会编译为Lambda表达式varresult=expr();//执行表达式result.Dump();//42,注意最后的语句的值就是Lambda表达式的值

解释:Block块相当于大括号{},在此例中共有三个语句Write("Hello"),WriteLine("World!"),42注意最后的语句的值就是Lambda表达式的返回值.写成常规语句就是:

publicintfunc(){Console.Write("Hello");Console.WriteLine("World!");return42;}func();示例2:

将简单Lambda表达式:(x,y)=x+y

用表达式树形式表示出来

//组装表达式树usingSystem.Linq.Expressions;ParameterExpressionpara1=Expression.Parameter(typeof(int),"x");ParameterExpressionpara2=Expression.Parameter(typeof(int),"y");varparas=newParameterExpression[]{para1,para2};BinaryExpressionbody=Expression.Add(para1,para2);varexpression=Expression.Lambda(body,paras);//编译表达式树varfunc=expression.Compile()asFuncint,int,int;//调用执行varres=func(1,2);Console.WriteLine($"表达式树的执行结果:(1,2)={res}");Console.WriteLine("HelloWorld!");Console.ReadLine();

执行结果:

组装表达式树执行结果

使用编译器的语法糖

//组装表达式树ExpressionFuncint,int,intexpression=(x,y)=x+y;//编译并调用varres=expression.Compile()(1,2);Console.WriteLine($"表达式树的执行结果:(1,2)={res}");Console.WriteLine("HelloWorld!");Console.ReadLine();

执行结果同上

本文作者:wwmin

1
查看完整版本: C表达式树及其应用Express