zl程序教程

您现在的位置是:首页 >  其它

当前栏目

Linq之Expression初见

LinQ expression
2023-09-14 09:01:00 时间

写在前面

系列文章

Expression

表达式树创建方式

一个例子

总结

上篇文章介绍了扩展方法,这篇文章开始将陆续介绍在linq中使用最多的表达式树的相关概念,以概念及例子一一列出如何在代码中使用Expression。

Linq之Lambda表达式初步认识

Linq之Lambda进阶

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

Linq之扩展方法

Expression

还是老样子,首先看MSDN中对表达式树的描述

表达式树以树形数据结构表示代码,其中每一个节点都是一种表达式,比如方法调用和 x y 这样的二元运算等。

你可以对表达式树中的代码进行编辑和运算。 这样能够动态修改可执行代码、在不同数据库中执行 LINQ 查询以及创建动态查询。 

表达式树又称为“表达式目录树”,以数据形式表示语言级代码,它是一种抽象语法树或者说是一种数据结构。

通过上面的描述,你会发现表达式树的作用:动态修改可执行代码、在不同数据库中执行Linq查询及创建动态查询。那它是如何做到的呢?那下面就开始咱们的表达式树之旅吧。

表达式树创建方式

表达式树创建方式分为两种:以lambda表达式的方式创建,通过API静态方法创建。

若 lambda 表达式被分配给 Expression TDelegate 类型的变量,则编译器可以发射代码以创建表示该 lambda 表达式的表达式树。

看一个例子:

1 static void Main(string[] args)

3 System.Linq.Expressions.Expression Func int, bool lambda = num = num = 5;

4 }

上面的代码意思就以表达式目录树的形式将强类型的lambda表达式num= num =5标识为数据结构。

通过 API 创建表达式树需要使用 Expression 类。

该类包含创建特定类型表达式树节点的静态工厂方法,比如表示参数变量的 ParameterExpression,或者是表示方法调用的 MethodCallExpression。 System.Linq.Expressions 名称空间还解释了 ParameterExpression、MethodCallExpression和另一种具体表达式类型。 这些类型来源于抽象类型 Expression。

那么我使用API的方式创建上面例子中的表达式树:

说的很高大上,其实就是类Expression的一系列静态方法。

首先引入命名空间

using System.Linq.Expressions;
复制代码
 1 static void Main(string[] args)

 3 //创建lambda表达式 num= num =5

 4 //第一步创建输入参数,参数名为num,类型为int类型

 5 ParameterExpression numParameter = Expression.Parameter(typeof(int), "num");

 6 //第二步创建常量表达式5,类型int

 7 ConstantExpression constant = Expression.Constant(5, typeof(int));

 8 //第三步创建比较运算符 =,大于等于,并将输入参数表达式和常量表达式输入

 9 //表示包含二元运算符的表达式。BinaryExpression继承自Expression

10 BinaryExpression greaterThanOrEqual = Expression.GreaterThanOrEqual(numParameter, constant);

11 //第四步构建lambda表达式树

12 //Expression.Lambda Func int, bool :通过先构造一个委托类型来创建一个 LambdaExpression

13 Expression Func int, bool lambda = Expression.Lambda Func int, bool (greaterThanOrEqual, numParameter);

14 }
复制代码

 

通过上面的代码你会发现这种方式在创建的时候,lambda表达式的左右及二元运算符都要分别的创建,然后在通过Expression.Lambda方法构建lambda表达式。

在 .NET Framework 4 中,API 表达式树还支持赋值表达式和控制流表达式,比如循环、条件块和 try-catch 块等。

看一个例子,通过API表达式树创建一个利用循环求1到n的和的表达式树。

如果能这样写该有多好啊

复制代码
1 Expression Func int, int lambda = n = 

3 int result = 0;

4 for (int j = n; j = 0; j--)

6 result += j;

8 return result;

9 };
复制代码

可惜

通过API创建表达式树,可以创建更为复杂的表达式树,这里先尝尝鲜

复制代码
 1 class Program

 3 static void Main(string[] args)

 5 //变量表达式

 6 ParameterExpression i = Expression.Variable(typeof(int), "i");

 7 //变量表达式

 8 ParameterExpression sum = Expression.Variable(typeof(int), "sum");

 9 //跳出循环标志

10 LabelTarget label = Expression.Label(typeof(int));

11 //块表达式

12 BlockExpression block =

13 Expression.Block(

14 //添加局部变量

15 new[] { sum },

16 //为sum赋初值 sum=1

17 //Assign表示赋值运算符

18 Expression.Assign(sum, Expression.Constant(1, typeof(int))),

19 //loop循环

20 Expression.Loop(

21 //如果为true 然后求和,否则跳出循环

22 Expression.IfThenElse(

23 //如果i =0

24 Expression.GreaterThanOrEqual(i, Expression.Constant(0, typeof(int))),

25 //sum=sum+i;i++;

26 Expression.AddAssign(sum, Expression.PostDecrementAssign(i)),

27 //跳出循环

28 Expression.Break(label, sum)

29 ), label

30 ) // Loop ends

31 );

32 int resutl = Expression.Lambda Func int, int (block, i).Compile()(100);

33 Console.WriteLine(resutl);

34 Console.Read();

36 }
复制代码

输出结果

本篇文章主要介绍了表达式树的概念及两种创建方式。在文章的结尾给出了一个例子,也是先尝尝鲜,对于代码中的一些静态方法可先参考注释。下篇文章将介绍一些Expression的常用的静态方法。

参考文章

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


博客版权: 本文以学习、研究和分享为主,欢迎转载,但必须在文章页面明显位置给出原文连接。
如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步!
再次感谢您耐心的读完本篇文章。http://www.cnblogs.com/wolf-sun/p/4222473.html
本文提供全流程,中文翻译。 Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例)