Linq之Expression高级篇(常用表达式类型)

目录

写在前面

系列文章

变量表达式

常量表达式

条件表达式

赋值表达式

二元运算符表达式

一元运算符表达式

循环表达式

块表达式

总结

写在前面

首先回顾一下上篇文章的内容,上篇文章介绍了表达式树的解析和编译。如果忘记了,可以通过下面系列文章提供的入口进行复习。这篇文章将介绍常见的表达式类型。

常见的表达式类型都有个共同的基类Expression。创建这些类型的对象,是通过API的方式创建的(也就是Expression的静态方法),首先引入命名空间:

1 using System.Linq.Expressions;

系列文章

Linq之Lambda表达式初步认识

Linq之Lambda进阶

Linq之隐式类型、自动属性、初始化器、匿名类

Linq之扩展方法

Linq之Expression初见

Linq之Expression进阶

变量表达式

在表达式树中使用ParameterExpression或者ParameterExpression表达式表示变量类型,下面看一个例子,我们定义一个int类型的变量i:

  // ParameterExpression表示命名的参数表达式。ParameterExpression i = Expression.Parameter(typeof(int),"i");

或者使用

1 ParameterExpression j = Expression.Variable(typeof(int), "j");

通过f12转到定义,发现这两个方法的注释几乎是一样的。静态方法Parameter第一个参数:定义的参数类型,第二个参数:为参数名称。

常量表达式

在表达式树中使用ConstantExpression表达式表示具有常量值的表达式。,看一个例子,我们定义一个int类型的常量5.并将该值赋值给上面定义的变量i

1             // ParameterExpression表示命名的参数表达式。
2             ParameterExpression i = Expression.Parameter(typeof(int), "i");
3             //ParameterExpression j = Expression.Variable(typeof(int), "j");
4             ConstantExpression constExpr = Expression.Constant(5, typeof(int));
5             // 创建一个表示赋值运算的 System.Linq.Expressions.BinaryExpression
6             //表示包含二元运算符的表达式。
7             BinaryExpression binaryExpression = Expression.Assign(i, constExpr);

Constrant方法第一个参数:常量,第二个参数为什么类型的常量。

这里提到了BinaryExpression表达式,该表达式标识包含二元运算符的表达式,类似与=,>这样的二元表达式都可以使用BinaryExpression表达式来表示。

调试模式下,在自动窗口查看当前表达式的DebugView属性,这个属性在调试表达式树的时候是非常有用的:

变量:

常量:

二元表达式:

通过观察上面的图,可知变量调试模式下DebugView属性将显示前面带有“$”符号的 ParameterExpression 变量名称。那么如果参数没有名称,则会为其分配一个自动生成的名称,例如 $var1 或 $var2(这里不再举例)。

条件表达式

在很多时候,我们都需要使用条件表达式来过滤一些数据,然后返回满足条件的数据,在表达式中有这样一些表达式满足你的需求。

常见运算符

>,>=

<,<=

if....then:如果满足条件那么..

if...then...else:如果满足条件执行某某代码,否则执行另外的逻辑

一个例子

IfThenElse方法

1 public static ConditionalExpression IfThenElse(
2     Expression test,
3     Expression ifTrue,
4     Expression ifFalse
5 )
 1             bool test = true;
 2             ConditionalExpression codition = Expression.IfThenElse(
 3                 //条件
 4                 Expression.Constant(test),
 5                 //如果条件为true,调用WriteLine方法输出“条件为true”
 6                  Expression.Call(
 7                  null,
 8                  typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }),
 9                  Expression.Constant("条件为true")
10                  ),
11                 //如果条件false
12                   Expression.Call(
13                  null,
14                  typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }),
15                  Expression.Constant("条件为false")
16                  )
17                  );
18             //编译表达式树,输出结果
19             Expression.Lambda<Action>(codition).Compile()();

输出结果

 例子描述:条件test包装为常量表达式,因为test为true,所以执行iftrue的表达式,并调用WriteLine方法打印出信息。

赋值表达式

=

还以上面为变量i赋值的例子为例

1             ParameterExpression i = Expression.Parameter(typeof(int), "i");
2             //ParameterExpression j = Expression.Variable(typeof(int), "j");
3             ConstantExpression constExpr = Expression.Constant(5, typeof(int));
4             // 创建一个表示赋值运算的 System.Linq.Expressions.BinaryExpression
5             //表示包含二元运算符的表达式。
6             BinaryExpression binaryExpression = Expression.Assign(i, constExpr);

+=

1 BinaryExpression b2 = Expression.AddAssign(i, constExpr);

-=

1 BinaryExpression b3 = Expression.SubtractAssign(i, constExpr);

*=

 BinaryExpression b4 = Expression.MultiplyAssign(i, constExpr);

/=

1 BinaryExpression b5= Expression.DivideAssign(i, constExpr);

举一个例子

 1  ParameterExpression i = Expression.Parameter(typeof(int), "i");
 2             BlockExpression block = Expression.Block(
 3                 new[] { i },
 4                 //赋初值 i=5
 5                 Expression.Assign(i, Expression.Constant(5, typeof(int))),
 6                 //i+=5 10
 7                 Expression.AddAssign(i, Expression.Constant(5, typeof(int))),
 8                 //i-=5 5
 9                 Expression.SubtractAssign(i, Expression.Constant(5, typeof(int))),
10                 //i*=5 25
11                Expression.MultiplyAssign(i, Expression.Constant(5, typeof(int))),
12                 //i/=5 5
13                Expression.DivideAssign(i, Expression.Constant(5, typeof(int)))
14                );
15             Console.WriteLine(Expression.Lambda<Func<int>>(block).Compile()());

结果

二元运算符表达式

在上面也提到了部分二元运算符表达式,类似加减乘除这样的运算符,对于二元运算符,就不再举例。这些返回的表达式树,都可以使用BinaryExpression来接收,或者使用基类Expression接收,或者更省事,使用var关键字。

一元运算符表达式

类似++,--运算符

i++等价于i=i+1,运算顺序就是i先加1,然后再赋值给i。在表达式书中使用Expression的PostIncrementAssign方法来进行自增或者自减操作。返回结果为UnaryExpression类型,同样可以使用基类Expression接收,或者var。

循环表达式

在表达式树中使用Expression的Loop方法实现循环。

块表达式

在前面的文章中,也说了不能使用Lambda方式创建带块级的表达式树,不然会有如下的错误

通过API的方式可以创建块级表达式树,其中Expression的Block方法功不可没。例如上面的加减乘除的例子中,可以包括多个Expression。

那么,下面就举一个包含自增的一元表达式,循环的表达式块,并输出结果。

输出1-100之间的所有偶数。

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             //变量i
 6             ParameterExpression i = Expression.Parameter(typeof(int), "i");
 7             //跳出循环
 8             LabelTarget label = Expression.Label();
 9             BlockExpression block = Expression.Block(
10                 new[] { i },
11                 //为i赋初值
12                 Expression.Assign(i, Expression.Constant(1, typeof(int))),
13                 Expression.Loop(
14                     Expression.IfThenElse(
15                       //如果i<=100
16                       Expression.LessThanOrEqual(i, Expression.Constant(100, typeof(int))),
17                      //如果为true.进入循环体
18                         Expression.Block(
19                              Expression.IfThen(
20                              //条件i%2==0;
21                                     Expression.Equal(Expression.Modulo(i, Expression.Constant(2, typeof(int))), 
22                                     Expression.Constant(0, typeof(int))),
23                                     Expression.Call(typeof(Console).GetMethod("WriteLine", 
24                                     new Type[] { typeof(int) }), new[] { i })),
25                              //i++
26                              Expression.PostIncrementAssign(i)
27                 ),
28                 //如果i>100
29                 Expression.Break(label)),
30                 label
31                 ));
32             Expression.Lambda<Action>(block).Compile()();
33             Console.Read();
34         }
35     }

结果

总结

本篇文章介绍了几种常见的表达式类型,当然,还有很多并没有列出,比如switch case,try catch等。如果在项目中需要创建复杂的表达式树,Expression的静态方法Block是必不可少的。希望通过本篇的学习,对你了解Expression有所帮助。

参考文章

https://msdn.microsoft.com/zh-cn/library/dd323961(v=vs.110).aspx

https://msdn.microsoft.com/zh-cn/library/bb397951.aspx

转载于:https://www.cnblogs.com/wolf-sun/p/4234747.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400904.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NetCore框架WTM的分表分库实现

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

WordPress WP Photo Album Plus插件‘wppa-tag’跨站脚本漏洞

漏洞名称&#xff1a;WordPress WP Photo Album Plus插件‘wppa-tag’跨站脚本漏洞CNNVD编号&#xff1a;CNNVD-201301-458发布时间&#xff1a;2013-01-24更新时间&#xff1a;2013-01-24危害等级&#xff1a; 漏洞类型&#xff1a;跨站脚本威胁类型&#xff1a;远程CVE编号&…

SpringCloudAlibaba分布式流量控制组件Sentinel实战与源码分析(上)

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

【单元测试框架unittest】

转载于:https://www.cnblogs.com/ppppying/p/6899750.html

C++ 炼气期之基本结构语法中的底层逻辑

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

优惠券的工厂与策略模式实现方案

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

WP8.1学习系列(第九章)——透视Pivot开发指南

Windows Phone 8 的 Pivot 控件 2014/6/18 适用于&#xff1a;Windows Phone 8 和 Windows Phone Silverlight 8.1 | Windows Phone OS 7.1 Windows Phone Pivot 应用提供了一种快速管理视图或页面的方法。该方法可以用于筛选大型数据集、查看多个数据集或切换应用视图。例如&a…

ESP8266 系统环境搭建

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

无线网络配置

转载于:https://www.cnblogs.com/lingxzg/archive/2013/02/09/2909606.html

Java编程之反射中的注解详解

“注解”这个词&#xff0c;可谓是在Java编程中出镜率比较高&#xff0c;而且也是一个老生常谈的话题。我们之前在聊Spring相关的东西时&#xff0c;注解是无处不在&#xff0c;之前我们简单的聊过一些“注解”的相关内容&#xff0c;比如在Spring中是如何进行“注解”组合的。…

SCCM 2012 R2实战系列之十三:辅助站点部署

由于最近几个月一直处于AD升级项目中&#xff0c;很久没有更新SCCM的技术文档了。SCCM 2012中的辅助站点部署方法还是比较特别的&#xff0c;需要注意的地方也非常多&#xff0c;今天跟大家分享辅助站点的具体部署和配置方法。1. 前提条件加入域环境 安装IIS组件安装BITS和远程…

DevOps落地实践点滴和踩坑记录-(1)

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

2014年度优秀员工代表发言稿

2019独角兽企业重金招聘Python工程师标准>>> 尊敬的各位领导和亲爱的同事们&#xff0c;大家好&#xff01; 作为优秀员工代表在这里发言&#xff0c;我很感谢刘总、周总、李总、漆总以及公司各层领导的信任和支持&#xff01;我感到十分荣幸&#xff0c;同时也感到…

无需另配定时器在STM32 HAL下实现微秒级延时(兼容FreeRTOS)

目录前言一、代码部分二、使用和验证1.引入头文件2.初始化3.使用和验证三、可移植性总结前言 接触HAL库差不多两年了&#xff0c;一直苦于HAL库没有自带微秒级的延时&#xff0c;网上的前辈们给出的解决方案要么是改写HAL_Delay的延时时间&#xff0c;要么就是额外占用一个定时…

×××S 2012 交互式报表 -- 同步交互式排序

S 2012 交互式报表 -- 同步交互式排序步骤1&#xff1a;首先&#xff0c;在刚才的“交互式排序”示例报表中再拖拉一个“Chart”&#xff0c;设置为长条图&#xff0c;从报表数据窗口中将销售金额、销售数量拖至“Values”&#xff0c;将产品大类拖放至“Category Groups”区域…

SpringCloud GateWay 万字详解

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

STM32 HAL 硬件IIC+DMA+简单图形库控制OLED

目录前言一、建立工程二、编写和移植前期准备驱动部分修改三、使用和验证结论&#xff08;2022年1月22日重制&#xff09;本文主要是移植带简单图形库的程序&#xff0c;如果只是实现DMA控制&#xff0c;建议看【0.96寸 OLED屏实现1500Fps的帧率】STM32 软件、硬件SPI、I2C驱动…

python创建分类器小结

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

SPOJ 1676 矩阵乘法+DP

题意&#xff1a; 给定N (1 ≤ N ≤ 10)个长度不超过6的单词,求由大写字母组成长度为L的包含至少一个给定单词的字符串有多少种,答案 mod 10007,(1 ≤ L ≤ 10^6)。 题解&#xff1a; 这个题最早是在一个关于trie图的论文中看到了&#xff0c;最近jzh又讲到了这个题&#xff0c…

go-zero微服务实战系列(三、API定义和表结构设计)

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…