C# 表达式树

C# 中的执行表达式树(Expression Tree) 阅读详情

创建表达式树

继承 Object -> Expression -> LambdaExpression -> Expression< TDelegate>

Expression 类

官方文档

  • 用于创建不同类型的表达式, 有很多方法如下面两个示例:
    • 如 Loop(Expression) 创建具有给定主体的 LoopExpression。
      • LoopExpression 表示无限循环。 可通过“中断”退出该循环。
    • GreaterThanOrEqual(Expression, Expression) 创建一个表示“大于或等于”数值比较的 BinaryExpression。
      • BinaryExpression 类 表示具有二进制运算符的表达式。
  • Lambda方法 值得注意:创建一个表示 Lambda 表达式的表达式树。返回类型是LambdaExpression
    • 参数:
    • delegateType Type:一个 Type,它表示 lambda 的委托签名。
    • body Expression:要将 Expression 属性设置为与其相等的 Body。
    • name String lambda 的名称。 用于发出调试信息。
    • tailCall Boolean 一个 Boolean,指示在编译创建的表达式时是否将应用尾调用优化。
    • parameters IEnumerable< ParameterExpression> 一个 IEnumerable< T>,包含用来填充 ParameterExpression 集合的 Parameters 对象。

Expression< TDelegate> 类

官方文档

  • 将强类型化的 Lambda 表达式表示为表达式树形式的数据结构。 此类不能被继承。
  • 作用是将参数传给LambdaExpression
  • Compile 方法
    • 将表达式树描述的 lambda 表达式编译为可执行代码,并生成表示 lambda 表达式的委托。
    • System.Linq.Expressions.Expression<Func<int, bool>> expr = i => i < 5;
    • Func<int, bool> deleg = expr.Compile();
  • Update

LambdaExpression

官方文档

  • 由它把我们表达式的主体,名称,以及参数保存着。
  • Compile() 方法 生成表示 lambda 表达式的委托。
  • 该 LambdaExpression 类型以表达式树的形式表示 lambda 表达式。
  • 派 Expression< TDelegate> 生 LambdaExpression 自和捕获 lambda 表达式类型的类型也可用于表示 lambda 表达式。
  • 在运行时,表示 lambda 表达式的表达式树节点始终为类型 Expression< TDelegate>。
  • NodeType属性值LambdaExpression为 Lambda.
  • 使用 Lambda 工厂方法创建对象 LambdaExpression 。

示例 循环输入10次

// 创建 loop表达式体来包含我们想要执行的代码  表示 一个循环
LoopExpression loop = Expression.Loop(
    Expression.Call(
        null,
        typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }),
        Expression.Constant("Hello"))
        );
 
// 创建一个代码块表达式包含我们上面创建的loop表达式,其中Expression.Block方法的参数是一个循环
BlockExpression block = Expression.Block(loop);
 
// 通过lambda方法 创建一个表示 Lambda 表达式的表达式树。
Expression<Action> lambdaExpression =  Expression.Lambda<Action>(block);
//通过Compile 方法生成表示 lambda 表达式的委托。最后通过Invoke方法调用委托
lambdaExpression.Compile().Invoke();
// 创建 loop表达式体来包含我们想要执行的代码
using System.Linq.Expressions;


//示一个标签,可以将该标签放置在任何 Expression 上下文中。 如果已跳转到该标签,则它将获取由对应的 GotoExpression 提供的值。
//否则,它接收 DefaultValue 中的值。 如果 Type 等于 System.Void,则不应提供值。
LabelTarget labelBreak = Expression.Label();

//表示一个命名的参数表达式
ParameterExpression loopIndex = Expression.Parameter(typeof(int), "index");

//创建一个 BlockExpression,其中包含给定的变量和表达式。
BlockExpression block = Expression.Block(
new[] { loopIndex },
//   创建一个表示赋值运算的 BinaryExpression。  声明了一个 初始化loopIndex =1
    Expression.Assign(loopIndex, Expression.Constant(1)),

    //1.创建 loop表达式体来包含我们想要执行的代码  表示 一个循环, 
    Expression.Loop(
        Expression.IfThenElse(
            // if 的判断逻辑
            Expression.LessThanOrEqual(loopIndex, Expression.Constant(10)),
            // 判断逻辑通过的代码
            Expression.Block(
                //Call  表达式体包含对静态方法或实例方法的调用。
                Expression.Call(
                    null,
                    typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }),
                    Expression.Constant("Hello")),
                Expression.PostIncrementAssign(loopIndex)),
            // 判断不通过的代码
            Expression.Break(labelBreak)
            ), labelBreak));



//   通过lambda方法 创建一个表示 Lambda 表达式的表达式树。
Expression<Action> lambdaExpression =  Expression.Lambda<Action>(block);
//通过Compile 方法生成表示 lambda 表达式的委托。最后通过Invoke方法调用委托
lambdaExpression.Compile().Invoke();


//block的Debuger View

//.Block(System.Int32 $index) {
//    $index = 1;
//    .Loop  {
//        .If($index <= 10) {
//            .Block() {
//                .Call System.Console.WriteLine("Hello");
//                $index++
//            }
//        } .Else {
//            .Break #Label1 { }
//        }
//    }
//    .LabelTarget #Label1:
//}


//Lambda方法调用后 lambdaExpression的 Debuger View

//.Lambda #Lambda1<System.Action>() {
//    .Block(System.Int32 $index) {
//        $index = 1;
//        .Loop  {
//            .If($index <= 10) {
//                .Block() {
//                    .Call System.Console.WriteLine("Hello");
//                    $index++
//                }
//        } .Else {
//                .Break #Label1 { }
//            }
//    }
//        .LabelTarget #Label1:
//    }
//}

// 直接返回常量值
ConstantExpression ce1 = Expression.Constant(10);

// 直接用我们上面创建的常量表达式来创建表达式树
Expression<Func<int>> expr1 = Expression.Lambda<Func<int>>(ce1);
Console.WriteLine(expr1.Compile().Invoke());
// 10

// --------------在方法体内创建变量,经过操作之后再返回------------------

//返回的值所在的表达式写在block的最后一个参数

// 1.创建方法体表达式 2.在方法体内声明变量并附值 3. 返回该变量
ParameterExpression param2 = Expression.Parameter(typeof(int));
BlockExpression block2 = Expression.Block(
    new[] { param2 },
    Expression.AddAssign(param2, Expression.Constant(20)),
    param2
    );
Expression<Func<int>> expr2 = Expression.Lambda<Func<int>>(block2);
Console.WriteLine(expr2.Compile().Invoke());
// 20

// -------------利用GotoExpression返回值-----------------------------------

// 创建一个 LabelTarget,它表示具有 void 类型但没有名称的标签  用于表示 GotoExpression 的目标。 
LabelTarget returnTarget = Expression.Label(typeof(Int32));


//创建一个 LabelExpression,它表示具有给定默认值的标签
//表示一个标签,可以将该标签放置在任何 Expression 上下文中。
//如果已跳转到该标签,则它将获取由对应的 GotoExpression 提供的值。
//否则,它接收 DefaultValue 中的值。 如果 Type 等于 System.Void,则不应提供值。
LabelExpression returnLabel = Expression.Label(returnTarget, Expression.Constant(100, typeof(Int32)));

// 为输入参加+10之后返回
ParameterExpression inParam3 = Expression.Parameter(typeof(int));

BlockExpression block3 = Expression.Block(
    Expression.AddAssign(inParam3, Expression.Constant(10)),
    //创建一个表示 return 语句的 GotoExpression。 可以指定在跳转时传递给标签的值。
    Expression.Return(returnTarget, inParam3),
    returnLabel
    );

Expression<Func<int, int>> expr3 = Expression.Lambda<Func<int, int>>(block3, inParam3);
Console.WriteLine(expr3.Compile().Invoke(20));
// 30


//简单的switch case 语句 来返回值

ParameterExpression genderParam = Expression.Parameter(typeof(int));
SwitchExpression switchExpression = Expression.Switch(
    genderParam,
    Expression.Constant("不详"),//默认值
    Expression.SwitchCase(Expression.Constant("男"), Expression.Constant(1)),
    Expression.SwitchCase(Expression.Constant("女"), Expression.Constant(0))
    //你可以将上面的Expression.Constant替换成其它复杂的表达式,ParameterExpression, BinaryExpression等, 这也是表达式灵活的地方,
    //因为归根结底它们都是继承自Expression, 而基本上我们用到的地方都是以基类作为参数类型接受的,所以我们可以传递任意类型的表达式。
    );
Expression<Func<int, string>> expr4 = Expression.Lambda<Func<int, string>>(switchExpression, genderParam);

遍历表达式树

C# 表达式树详解 阅读详情

相关推荐

C#中的Lambda表达式和表达式树

Lambda—— 表达式 "Lambda表达式"是一个匿名函数,是一种高效的类似于函数式编程的表达式,Lambda简化了开发中需要编写的代码量。它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型,支持带有可绑定到委托或表达式树的输入参数的内联表达式。所有Lambda表达式都使用Lambda运算符=>,该运算符读作"goes to"。Lambda运算符的左边是输入参数(如果有),...

起个名字好难啊 1247

C#-表达式树

1、表达式树   表达式树,在C#中是Expression来定义的,它是一种语法树,或者说是一种数据结构。其主要用于存储需要计算、运算的一种结构,它只提供存储功能,不进行运算。通常Expression是配合Lambda一起使用,lambda可以是匿名方法。Expression可以动态创建。 声明一个lambda表达式,其中可以指明类型,也可以是匿名方法: //Func<int, int, int> func = new Func<int, int, int>((m, n) =>

chinaherolts2008的博客 2859

C# 表达式树:5大绝招,让你轻松掌握

表达式树是一种树形数据结构,用于表示代码中的表达式。每个节点代表表达式中的一个元素,如常量、变量、方法调用等。LINQ 查询:在 LINQ 中,查询表达式被转换为表达式树,然后由查询提供器解析和执行。动态代码生成:可以在运行时动态生成和执行代码。数据绑定:在 WPF 等 UI 框架中,用于定义数据绑定的条件。反射:在运行时构建方法调用和访问属性。通过本文的详细介绍,相信你已经掌握了 C# 表达式树的基本概念和使用方法。

java专栏 2176

C# 中的表达式树

目录前言:一、使用lambda声明表达式树二、表达式树的分解三、表达式树实现实体映射四、表达式树的访问或重写五、表达式树的Sql拼装 前言: 我们在工作当中,经常会接触到与表达式树相关的内容,比如 EF,EF Core中的 lambda,就是表达式树。 表达式树是一种数据结构,一个能拼装能解析的数据结构。 一、使用lambda声明表达式树 以下代码演示声明表达式树和表达式树转换为委托。 // lambda表达式 声明表达式目录树,是一个数据结构 (快捷方式) Expression<Fu

MaleDeer 1946

微前端实战:MicroApp内存泄漏优化策略与性能调优

本文分享了在大型后台管理系统微前端化过程中,使用MicroApp框架时遇到的内存泄漏实战问题与优化策略。通过深入分析沙箱机制,提出动态加载、精准卸载、沙箱配置优化及第三方库补丁等核心方案,并结合Vue/React子应用专项检查清单,有效解决了内存占用飙升问题,为微前端架构的性能调优提供了系统性解决方案。

weixin_29014939的博客 277

WPF毛玻璃效果别再写C#代码了!纯XAML用Border+VisualBrush+BlurEffect三步搞定

本文详细介绍了如何在WPF中通过纯XAML实现毛玻璃效果,无需编写C#代码。通过VisualBrush、BlurEffect和Clip的黄金组合,开发者可以快速创建专业级的毛玻璃面板,提升UI的现代感和视觉层次。文章还提供了性能优化技巧和实战案例,帮助开发者在各种场景中高效应用这一技术。

weixin_28630185的博客 352

C# 表达式树的简介与说明

表达式树是 C# 中强大而灵活的特性,它使得我们可以在运行时动态地生成、编译和执行代码。通过使用表达式树,我们能够在不预先知道代码结构的情况下,以编程的方式操作和构建代码逻辑。表达式树在 LINQ 查询、动态查询和动态代码生成等场景中有着广泛的应用,是 C# 编程中不可或缺的一部分。

qq_35320456的博客 1808

WSL中使用VMD图形化界面

【代码】WSL中使用VMD图形化界面。

handsome213的博客 840

C# Lambda表达式和表达式树(二):表达式树

以编程方式构建表达式树 System.Linq.Expressions命名空间包含了代表表达式的各个类,它们都继承自Expression Expression类包含两个属性 Type属性代表表达式求值后的.NET类型,可把它视为一个返回类型,例如,如果一个表达式要获取一个字符串的Length属性,该表达式的类型是int。 NodeType属性返回所代表的表达式的种类。它是Express...

lionheart922的专栏 1645

STM32裸机开发基础:寄存器直接操作详解

寄存器是微控制器内部的特殊存储单元,直接与硬件电路连接,用于控制和监视硬件功能。与普通内存不同,寄存器的每一位(bit)通常都有特定的硬件含义。寄存器就是机器的控制面板上的各种开关和指示灯每个开关控制一个具体功能(如打开LED、启动通信)每个指示灯显示一个具体状态(如数据接收完成、错误发生)// GPIO引脚定义1。

2401_88760782的博客 2187

TLS回调函数–一文看懂(详)

TLS回调函数 CTF RE

Joyce_hjll的博客 3734

【C#高级编程】—表达式树详解

表达式树是一种强大的工具,它允许你将代码逻辑表示为数据结构,并在运行时分析和操作这些逻辑。它的核心作用包括动态生成代码、分析代码逻辑以及与外部系统交互。表达式树在 LINQ、ORM 框架(如 Entity Framework)和动态查询等场景中发挥着重要作用。

qq_3517289697的博客 1356

小红书图文AI创作:输入主题,一键生成图文(coze工作流教程+获取)

输入主题,工作流一键生成小红书风格图文,30s一条,可批量生成

2301_79384090的博客 2800

C#中的Expression表达式树

C#中的表达式树这节课来了解一下表示式树是什么?在C#中,表达式树是一种数据结构,它可以表示一些代码块,如Lambda表达式或查询表达式。表达式树使你能够查看和操作数据,就像你可以查看和操作代码一样。它们通常用于创建动态查询和解析表达式。一、认识表达式树为什么要这样说?它和委托有什么区别?创建一个简单的表达式树和委托public class ExpressionDemo { vo...

dotNET跨平台 868

用STM32F103C8T6和TB6612驱动模块,从零搭建一辆能避障循迹的智能小车(附完整代码)

本文详细介绍了如何使用STM32F103C8T6和TB6612驱动模块从零搭建一辆能避障循迹的智能小车。内容涵盖硬件选型、电路设计、底层驱动配置以及智能行为算法实现,并附有完整代码示例,帮助开发者快速掌握嵌入式开发的核心技术。

weixin_42641741的博客 446

LLC谐振电路增益公式推导

LLC谐振电路增益公式理解

金凯*博客 1万+

C#表达式树

C#表达式树 表达式和表达式树 表达式可以是一个参数(如参数x),一个常数(如常数5),一个加运算(如x+5)等等,可以把几个小的表达式组装在一起成为大的表达式,例如:(x+5)-(++y)。对于这样一个表达式可以用一棵树来表示,如下: 这就是表达式树,表达式树本身也是一个表达式(大的表达式)。一个表达式也是一棵表达式树,可以说它是一棵小的表达式树。可以把表达式树和表达式认为是一...

Wlk1229 3721

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

C# Lambda表达式和表达式树

转载地址:https://blog.csdn.net/WuLex/article/details/126631259。

波波诸葛伟 645

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

手把手构建 C# 表达式树

表达式树()是用树型的数据结构来表示代码的运算逻辑。你的代码也是你可以用来操作的数据,数据也可以变成代码。当你拿到数据时(比如从数据库拿到数据),你可以通过这些数据创建出代码。这就是表达式树。说到这里,你可能完全不理解,我们慢慢探索。首先看一下表达式树的图。1 + 2这个表达式的表达式树:图 1假设我们先序遍历这棵树,首先我们拿到+,我们知道这是要进行一个加法操作,然后我们拿到1,再拿到2,我们就知道是要运算 1 和 2 相加的结果。1 + 2 * 3的表达式树(注意,乘的优先级高于加):图 21。

极客神殿 2055

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

C# 中的 表达式树

这节来讲一下C#中的表达式树(又称表达式目录树、Expression)。什么是表达式树?表达式树是一种C#中的数据结构,它以树的形式表示某些代码内部的结构。每个节点是一种称为表达式的C#对象,例如二元运算,方法调用,常量等。这种数据结构主要用于LINQ查询的内部机制和动态编程。在C#中,表达式树使在编译时表达式的结构和操作被保留下来,而不是像通常的.net代码那样被直接编译成IL。...

dotNET跨平台 441

C# 表达式树讲解(一)

一、前言 一直想写一篇Dpper的定制化扩展的文章,但是里面会设计到对Lambda表达式的解析,而解析Lambda表达式,就必须要知道表达式树的相关知识点。我希望能通过对各个模块的知识点或者运用能够多一点的讲解,能够帮助到园友了解得更多。虽然讲解得不全面,如果能成为打开这块的一把钥匙,也是蜗牛比较欣慰的。 表达式系列目录 C# 表达式树讲解(一) C# 表达式树遍历(二) C#...

CL10011314155的博客 564
上一篇: h3u汇川
WorldCode
博客等级 码龄8年 2粉丝 5原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值