表达式树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,泛型委托,表达式树
这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托,表达式树这些应用.今天我尝试用简单的方法叙述一下,让大家在五 ...
随机推荐
- FZU - 1989 AntiAC
Problem 1989 AntiAC Accept: 93 Submit: 444Time Limit: 4000 mSec Memory Limit : 32768 KB Prob ...
- CentOS6.8安装配置sonarqube6.4
下载最新版本的sonar(现在改名叫sonarqube) https://www.sonarqube.org/downloads/ 我下载的版本是Sonarqube6.4 1 使用前需要 ...
- [JLOI2015]装备购买 (高斯消元)
[JLOI2015]装备购买 \(solution:\) 首先这道题的题面已经非常清晰的告诉我们这就是线性空间高斯消元的一道题(可以用某些装备来表示另一件装备,这已经不能再明显了),只是这道题要求我们 ...
- python - 上下文管理协议(with + __enter__ + __exit__)
上下文管理协议: with + __enter__ + __exit__ #上下问管理协议: #with + __enter__ + __exit__ class Test(): def __init ...
- jquery中选择checkbox拼接成字符串,然后到后台拆分取值
jquery中选择checkbox拼接成字符串,然后到后台拆分取值 js中的代码 $("#btn").click(function(){ var chenked=$("i ...
- 【逆向工具】IDA使用1-VS2015版本debug查找Main函数,加载符号文件
IDA 常见操作 空格,切换反汇编视图 选择CALL或是跳转 进入函数内部或是跳转处 返回键 ESC daq.exe 分析32位程序 ,生成的IDA数据库文件是 .idb Idap64.exe 分析6 ...
- Vulcan 基于Meteor的APollO框架 , grapesjs 用于可视化生成Html 页面
Vulcan 基于Meteor的APollO框架 :http://vulcanjs.org/ grapesjs 用于可视化生成Html http://grapesjs.com/
- 信息检索(IR)的评价指标介绍 - 准确率、召回率、F1、mAP、ROC、AUC
原文地址:http://blog.csdn.net/pkueecser/article/details/8229166 在信息检索.分类体系中,有一系列的指标,搞清楚这些指标对于评价检索和分类性能非常 ...
- nodejs前端开发环境安装
1. nodejs安装 要求:node版本6.2.0及以上,npm版本3.8.9及以上 Nodejs安装包地址: 2. 在rTools上下载并安装git 3. 在rTools上 ...
- 解决walle报错:宿主机代码检出检测出错,请确认svn用户名密码无误
使用walle检测报错: 查看日志 # tail -f /tmp/walle/walle-20161010.log 报错: 2016-10-10 14:20:30 -- --------------- ...