目录

写在前面

系列文章

Expression

表达式树创建方式

一个例子

总结

写在前面

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

系列文章

Linq之Lambda表达式初步认识

Linq之Lambda进阶

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

Linq之扩展方法

Expression

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

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

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

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

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

表达式树创建方式

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

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

看一个例子:

   static void Main(string[] args)
{
System.Linq.Expressions.Expression<Func<int, bool>> lambda = num => num >= ;
}

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

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

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

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

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

首先引入命名空间

using System.Linq.Expressions;
         static void Main(string[] args)
{
//创建lambda表达式 num=>num>=5
//第一步创建输入参数,参数名为num,类型为int类型
ParameterExpression numParameter = Expression.Parameter(typeof(int), "num");
//第二步创建常量表达式5,类型int
ConstantExpression constant = Expression.Constant(, typeof(int));
//第三步创建比较运算符>=,大于等于,并将输入参数表达式和常量表达式输入
//表示包含二元运算符的表达式。BinaryExpression继承自Expression
BinaryExpression greaterThanOrEqual = Expression.GreaterThanOrEqual(numParameter, constant);
//第四步构建lambda表达式树
//Expression.Lambda<Func<int, bool>>:通过先构造一个委托类型来创建一个 LambdaExpression
Expression<Func<int, bool>> lambda = Expression.Lambda<Func<int, bool>>(greaterThanOrEqual, numParameter);
}

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

一个例子

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

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

如果能这样写该有多好啊

             Expression<Func<int, int>> lambda = n =>
{
int result = ;
for (int j = n; j >= ; j--)
{
result += j;
}
return result;
};

可惜

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

     class Program
{
static void Main(string[] args)
{
//变量表达式
ParameterExpression i = Expression.Variable(typeof(int), "i");
//变量表达式
ParameterExpression sum = Expression.Variable(typeof(int), "sum");
//跳出循环标志
LabelTarget label = Expression.Label(typeof(int));
//块表达式
BlockExpression block =
Expression.Block(
//添加局部变量
new[] { sum },
//为sum赋初值 sum=1
//Assign表示赋值运算符
Expression.Assign(sum, Expression.Constant(, typeof(int))),
//loop循环
Expression.Loop(
//如果为true 然后求和,否则跳出循环
Expression.IfThenElse(
//如果i>=0
Expression.GreaterThanOrEqual(i, Expression.Constant(, typeof(int))),
//sum=sum+i;i++;
Expression.AddAssign(sum, Expression.PostDecrementAssign(i)),
//跳出循环
Expression.Break(label, sum)
), label
) // Loop ends
);
int resutl = Expression.Lambda<Func<int, int>>(block, i).Compile()();
Console.WriteLine(resutl);
Console.Read();
}
}

输出结果

总结

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

参考文章

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

最新文章

  1. java spring 配置文件的读取
  2. php 使用htmlspecialchars() 和strip_tags函数过滤HTML标签的区别
  3. JavaScript获取浏览器类型与版本
  4. 常见HTTP状态码
  5. localStorage和sessionStorage
  6. iframe与主框架跨域相互访问方法【转】
  7. web api 限制单个IP在一定时间内访问次数
  8. MVC _ViewStart文件的作用
  9. ORACLE 单实例完全卸载数据库
  10. Codeforces Round #238 (Div. 2) D. Toy Sum 暴搜
  11. 第六届全球游戏大会( GMGC 北京 2017 )有哪些看点?
  12. org.apache.maven.archiver.MavenArchiver.getManifest(org.apache.maven.project.MavenProject, org.apache.maven.archiver.MavenArchiveConfiguration)
  13. [PHP]php缓冲 output_buffering的使用详解
  14. Spring杂记BeanFactory之getBean方法
  15. KeyTool 和 OpenSSL 相互转换 [转]
  16. Java线程总结---第一天
  17. python文件操作与字符编码
  18. Java中二叉排序树
  19. windows(32位 64位)下python安装mysqldb模块
  20. ubuntu系统安装mysql二进制压缩包(tar.gz)以及navicat远程连接服务器(linux系统)

热门文章

  1. spring 容器加载完成后执行某个方法
  2. 关于TouchEvent里面的touches,targetTouches,changedTouches的解释
  3. css中table tr:nth-child(even)改变tr背景颜色: IE7,8无效
  4. HDU 4282 A very hard mathematic problem --枚举+二分(或不加)
  5. 优化后的二次测试Miller_Rabin素性测试算法
  6. AC日记—— codevs 1031 质数环(搜索)
  7. [反编译U3D]Decompile Unity Resources
  8. WWW压缩解压缩
  9. java 16 - 9 增强for的概述和使用
  10. java12 - 7 排序的案例