表达式树ExpressionTrees
简介
表达式树以树形数据结构表示代码,其中每一个节点都是一种表达式,比如方法调用和 x < y 这样的二元运算等。
你可以对表达式树中的代码进行编辑和运算。这样能够动态修改可执行代码、在不同数据库中执行 LINQ 查询以及创建动态查询。
表达式树还能用于动态语言运行时 (DLR) 以提供动态语言和 .NET Framework 之间的互操作性。
一、Lambda 表达式创建表达式树
Expression<Action<int>> actionExpression = n => Console.WriteLine(n);
Expression<Func<int, bool>> funcExpression1 = (n) => n < ;
Expression<Func<int, int, bool>> funcExpression2 = (n, m) => n - m == ;
var lambda = actionExpression.Compile();
lambda();//输出11
Console.ReadLine();
二、API 创建表达式树
//通过 Expression 类创建表达式树
// lambda:num => num == 0
ParameterExpression pExpression = Expression.Parameter(typeof(int)); //参数:num
ConstantExpression cExpression = Expression.Constant(); //常量:0
BinaryExpression bExpression = Expression.MakeBinary(ExpressionType.Equal, pExpression, cExpression); //表达式:num == 0
Expression<Func<int, bool>> lambda = Expression.Lambda<Func<int, bool>>(bExpression, pExpression); //lambda 表达式:num => num == 0
var aa = lambda.Compile();
Console.WriteLine("{0}", aa()); //false
Console.WriteLine("{0}", aa()); //true
Console.ReadLine();
三、解析表达式树
Expression<Func<int, bool>> funcExpression = num => num == ;
//开始解析
ParameterExpression pExpression = funcExpression.Parameters[]; //lambda 表达式参数
BinaryExpression body = (BinaryExpression)funcExpression.Body; //lambda 表达式主体:num == 0
Console.WriteLine($"解析:{pExpression.Name} => {body.Left} {body.NodeType} {body.Right}");
Console.ReadLine();
四、表达式树永久性
表达式树应具有永久性(类似字符串)。这意味着如果你想修改某个表达式树,则必须复制该表达式树然后替换其中的节点来创建一个新的表达式树。 你可以使用表达式树访问者遍历现有表达式树。
五、编译表达式树
//Expression<TDelegate> 类型提供了 Compile 方法以将表达式树表示的代码编译成可执行委托。
Expression<Func<string, int>> funcExpression = msg => msg.Length;
//表达式树编译成委托
var lambda = funcExpression.Compile();
//调用委托
Console.WriteLine(lambda("Hello, World!")); //13 //语法简化
Console.WriteLine(funcExpression.Compile()("Hello, World!")); //
Console.ReadLine();
六、执行表达式树
int n = ;
int m = ;
var p1 = Expression.Parameter(typeof(int), "num1");
var p2 = Expression.Parameter(typeof(int), "num2");
//待执行的表达式树
BinaryExpression bExpression = Expression.Add(p1, p2);
//创建 lambda 表达式
Expression<Func<int,int,int>> funcExpression = Expression.Lambda<Func<int, int, int>>(bExpression, p1, p2);
//编译 lambda 表达式
Func<int, int, int> func = funcExpression.Compile(); //执行 lambda 表达式
Console.WriteLine($"{n} + {m} = {func(n,m)}");
Console.ReadLine();
七、修改表达式树
static void Main(string[] args)
{
Expression<Func<int, bool>> funcExpression = num => num == ;
Console.WriteLine($"Source: {funcExpression}");//Source: num => (num == 0) var visitor = new NotEqualExpressionVisitor();
var expression = visitor.Visit(funcExpression); Console.WriteLine($"Modify: {expression}");//Source: num => (num != 0) Console.Read();
} /// <summary>
/// 不等表达式树访问器
/// </summary>
public class NotEqualExpressionVisitor : ExpressionVisitor
{
public Expression Visit(BinaryExpression node)
{
return VisitBinary(node);
} protected override Expression VisitBinary(BinaryExpression node)
{
//该类继承 ExpressionVisitor 类,通过 Visit 方法间接调用 VisitBinary 方法将 != 替换成 ==。基类方法构造类似于传入的表达式树的节点,但这些节点将其子目录树替换为访问器递归生成的表达式树。
return node.NodeType == ExpressionType.Equal
? Expression.MakeBinary(ExpressionType.NotEqual, node.Left, node.Right) //重新弄个表达式:用 != 代替 ==
: base.VisitBinary(node);
}
}
表达式树ExpressionTrees的更多相关文章
- 不可不知的表达式树(1)Expression初探
说起Lambda表达式,大家基本都很熟悉了,而表达式树(Expression Trees),则属于80%的工作中往往都用不到的那种技术,所以即便不是什么新技术,很多人对其理解都并不透彻.此文意图从表达 ...
- ASP.NET Core中使用表达式树创建URL
当我们在ASP.NET Core中生成一个action的url会这样写: var url=_urlHelper.Action("Index", "Home"); ...
- LINQ Expresstion Tree 表达式树
Expression trees represent code in a tree-like data structure, where each node is an expression, for ...
- 表达式树(Expression Trees)
[翻译]表达式树(Expression Trees) 原文地址:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/con ...
- 表达式树(Expression Tree)
饮水思源 本文并非原创而是下面网址的一个学习笔记 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/e ...
- 再讲IQueryable<T>,揭开表达式树的神秘面纱
接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...
- [C#] C# 知识回顾 - 表达式树 Expression Trees
C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...
- 轻量级表达式树解析框架Faller
有话说 之前我写了3篇关于表达式树解析的文章 干货!表达式树解析"框架"(1) 干货!表达式树解析"框架"(2) 干货!表达式树解析"框架" ...
- 用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树
这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托,表达式树这些应用.今天我尝试用简单的方法叙述一下,让大家在五 ...
随机推荐
- 浅谈cookie与session的区别
cookie用的是在客户端保持状态的方案(它是在用户端的会话状态的存贮机制),前端也可以来设置他 所有浏览器都识别,并且会缓存在浏览器中. cookie是以key=value这种键值对的形式保存,每个 ...
- 交叉熵的数学原理及应用——pytorch中的CrossEntropyLoss()函数
分类问题中,交叉熵函数是比较常用也是比较基础的损失函数,原来就是了解,但一直搞不懂他是怎么来的?为什么交叉熵能够表征真实样本标签和预测概率之间的差值?趁着这次学习把这些概念系统学习了一下. 首先说起交 ...
- 第17月第28天 python yield
1. class Fab(object): def __init__(self, max): self.max = max self.n, self.a, self.b = 0, 0, 1 def _ ...
- HDU 2522 A simple problem (模拟)
题目链接 Problem Description Zty很痴迷数学问题..一天,yifenfei出了个数学题想难倒他,让他回答1 / n.但Zty却回答不了^_^. 请大家编程帮助他. Input 第 ...
- Java 学习札记(三)免安装版TomCat中tomcat6w.exe的运行
1.使用环境 很多时候我们用的是官网的解压免安装版的Tomcat,相比安装Tomcat除了少了安装步骤以外还少了tomcat6w.exe运行所需要的环境变量,所以一般Java开发免安装版的已经足够使用 ...
- 关于apache 开启 ssl https 支持 TLS1.2 的些事
项目背景 需要搭建一个小程序的服务器,当然要使用https协议服务器windows service 2012 r2,后台语言是php,服务集成环境装的是appserv2.5 ,apache2.2证书申 ...
- ubuntu14.04 提示 卷 文件系统根目录 仅剩余xxx的硬盘空间
- ubuntu14.04下 Kinect V2+Ros接口安装
1. 首先git下载代码,放到主文件夹下面 git clone https://github.com/OpenKinect/libfreenect2.git 2. 然后安装依赖项如下,最好事先编译安装 ...
- 所有Windows7下游戏的全屏问题
Win键+R键,打开运行窗口,输入regedit 回车,这样就打开了注册表编辑器,然后,定位到以下位置:HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\ ...
- 基于内容的图片检索CBIR简介
原文地址:http://blog.csdn.net/davebobo/article/details/53171311 传统的图像检索过程,先通过人工对图像进行文字标注,再利用关键字来检索图像,这种依 ...