栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C# > C#教程

C#表达式树的基本用法讲解

C#教程 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C#表达式树的基本用法讲解

   表达式树使用一种类似树的结构来表示代码,它的每个节点都是一个表达式,比如方法调用和x

   这一系列文章,主要是对C#表达式树的一种总结,基本知识参考MSDN的内容 这部分内容可以直接到MSDN上查看,后面的几篇文章主要分享一下,在工作中碰到的应用到表达式树的部分,谨做为记录和分享。

生成表达式树

通过lambda表达式创建表达式树
    可以通过将lambda表达式赋值给expression类型的变量,编译器可以自动生成创建该lambda表达式的表达式树。C#编译器只能从lambda表达式生成表达式树,只能是单行lambda表达式,不能解析多行lambda语句,如下,可以通过一下方式创建lambda表达式 num=>num<5的表达式树:

expression> lambda = num => num < 5; 

通过API创建表达式树

   使用API创建表达式,需要使用expression类,这个类包含了创建特定类型表达式树节点的静态工厂方法,比如表示参数的变量Parameterexpression,表示方法调用的Methodexpression。Parameterexpression,Methodexpression以及其他特定的表达式类型都在System.Linq.expression命名空间里定义,这些类型都派生于expression抽象类。

  下面的例子是使用API方式创建num=>num<5的lambda表达式对应的表达式树:

Parameterexpression numPara = expression.Parameter(typeof(int), "num");//参数num
Constantexpression five = expression.Constant(5, typeof(int));//常数5

Binaryexpression numLessThanFive = expression.LessThan(numPara, five);
expression> lambda1 = expression.Lambda>(numLessThanFive, new Parameterexpression[] { numPara });

    从.NET framework 4开始,表达式树API还支持赋值以及流程控制,比如循环,条件块和try ... catch块等。相对于通过lambda表达式创建表达式树,可以利用API创建更加复杂的表达式树,比如下面使用API创建数字阶乘的表达式树:

//参数value
Parameterexpression value = expression.Parameter(typeof(int), "value");
//本地变量
Parameterexpression result = expression.Parameter(typeof(int), "result");
//标签,用来跳出循环
LabelTarget label = expression.Label(typeof(int));
//创建表达式块
Blockexpression block = expression.Block(
 //添加本地参数result
 new[] { result },
 //result=1 赋值
 expression.Assign(result, expression.Constant(1)),
 //循环
 expression.Loop(
  //循环条件
  expression.IfThenElse(
   //如果 value>1
   expression.GreaterThan(value, expression.Constant(1)),
   //则 result*=value--;
   expression.MultiplyAssign(result, expression.PostDecrementAssign(value)),
   //否则跳出loop循环。跳到label的语句执行
   expression.Break(label, result)
   ),
   label
  )
);
//编译表达式树
Func factor = expression.Lambda>(block, value).Compile();
//执行,输出结果120
Console.WriteLine(factor(5));

解析表达式树

  在获取了表达式树之后,如何获取表达式树的每一个部分,这个在有些情况下非常有用,下面这个例子展示了如何获取num=>num<5的各个部分。

expression> expreTree = num => num < 5;

Parameterexpression param = (Parameterexpression)expreTree.Parameters[0];//num
Binaryexpression operation = (Binaryexpression)expreTree.Body;//<
Parameterexpression left = (Parameterexpression)operation.Left;//num
Constantexpression right = (Constantexpression)operation.Right;//5
  //output Decomposed expression: num => num LessThan 5 
Console.WriteLine("Decomposed expression:{0} = > {1} {2} {3}", param.Name, left.Name, operation.NodeType, right.Value);

编译表达式树

  expression类型有Compile方法,可以将表达式树编译成对应的TDelegate委托类型,使用方法如下:

// 创建表达式树
expression> expr = num => num < 5;
// 将表达式树编译成对应委托 
Func result = expr.Compile();
//调用委托方法,输出True
Console.WriteLine(result(4));
//也可以直接编译后调用,输出True
Console.WriteLine(expr.Compile()(4));

再比如,下面例子演示了,创建一个表达式树,然后编译执行:

//创建表达式树的执行逻辑
Binaryexpression be = expression.Power(expression.Constant(2D), expression.Constant(3D));
//创建表达式树
expression> le = expression.Lambda>(be);
//编译表达式树
Func compileexpression = le.Compile();
//执行lambda表达式,获得结果8
double result = compileexpression();
Console.WriteLine(result);

表达式树的修改

   表达式树是不可变对象(immutable),跟string类似,不能直接修改,只能复制一个然后重新构造。具体参考MSDN How to modify expression trees (C#).

结语

  本篇全部内容参考MSDN上表达式树部分的内容,如果有基础建议直接看,这里只是个人作为笔记,也是表达式树的最基础部分,后文会介绍表达式树的一些用法。

以上就是C#表达式树的基本用法讲解的详细内容,更多关于C#表达式树的资料请关注考高分网其它相关文章!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/121634.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号