服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C#表达式树基础教程

C#表达式树基础教程

2022-12-20 15:01痴者工良 C#

这篇文章介绍了C#表达式树的基础教程,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

什么是表达式树

来自微软官方文档的定义:

表达式树以树形数据结构表示代码。

它能干什么呢?

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

好不好玩?

表达式树还能用于动态语言运行时 (DLR) 以提供动态语言和 .NET Framework 之间的互操作性,同时保证编译器编写员能够发射表达式树而非 Microsoft 中间语言 (MSIL)。

哪里有应用?

ORM框架、工作流框架等,使用到 Lambda 的代码。。。动态执行代码、动态组装代码等。

创建表达式树

创建表达式树有两种方式:通过 lambda 表达式、通过 API。

创建表达式树的意思是,在此之前已经编写好每个结点,最后使用代码将所有结点组合起来,生成表达式树。

示例(通过API创建表达式树)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ParameterExpression a = Expression.Parameter(typeof(int), "i");
ParameterExpression b = Expression.Parameter(typeof(int), "j");
 
Expression r1 = Expression.Multiply(a, b);      //乘法运行
ParameterExpression c = Expression.Parameter(typeof(int), "x");
ParameterExpression d = Expression.Parameter(typeof(int), "y");
Expression r2 = Expression.Multiply(c, d);      //乘法运行
 
Expression result = Expression.Add(r1, r2);     //相加
//以上代码产生结点
//生成表达式
Expression<Func<int, int, int, int, int>> func = Expression.Lambda<Func<int, int, int, int, int>>(result, a, b, c, d);
var com = func.Compile();
Console.WriteLine("表达式" + func);
Console.WriteLine(com(12, 12, 13, 13));
Console.ReadKey();

上面关于表达式树的代码很多,以下这一步叫生成/创建表达式树。

?
1
Expression<Func<int, int, int, int, int>> func = Expression.Lambda<Func<int, int, int, int, int>>(result, a, b, c, d);

以下这句叫执行表达式树

?
1
var com = func.Compile();

其它代码是用于生成表达式树结点/逻辑。

回归正题,创建表达式树的两种方法。

lambda 创建表达式树

上面的表达式树示例,是用于生成

?
1
( i * j ) + ( x * y )

但是就这么简单的操作,要写这么长,实在不合理。

而通过 lambda ,可以这样写

?
1
Expression<Func<int, int, int, int, int>> func = (i, j, x, y) => (i * j) + (x * y);

如果使用 lambda 生成表达式树, lambda 只能使用单行语句,不能使用 if、for等语句。

具体关于 Lambda 的表达式树,后面其它文章有说明。

通过 API 创建表达式树

就是这样

?
1
Expression<Func<int, int, int, int, int>> func = Expression.Lambda<Func<int, int, int, int, int>>(result, a, b, c, d);

两种方式左边的都是一样的,区别在于等号右边。

Expression< TDelegate >

上面示例的最终结果都是生成

?
1
Expression<Func<int, int, int, int, int>> func

func 是表达式树变量。

我们可以了解以下表达式树具有的方法和属性。

用于生成表达式树结点的,是 Expression 类型。

那么,创建的表达式树 func ,是 Expression<TDelegate> 类型。

定义如下

?
1
public sealed class Expression<TDelegate> : LambdaExpression

具有方法如下

C#表达式树基础教程

方法 说明
Compile() 将表达式树描述的 lambda 表达式编译为可执行代码,并生成表示 lambda 表达式的委托。
Compile(Boolean) 将表达式树描述的 Lambda 表达式编译为已解释或已编译的代码,并生成表示该 Lambda 表达式的委托。
Compile(DebugInfoGenerator) 将 lambda 编译到方法定义中。 (Inherited from LambdaExpression)
Update(Expression, IEnumerable) 创建一个与此表达式类似的新表达式,但使用所提供的子级。 如果所有子级都相同,则将返回此表达式。
Accept(ExpressionVisitor) 调度到此节点类型的特定 Visit 方法。 例如,MethodCallExpression调用 VisitMethodCall。

由于 Expression<TDelegate> 继承了 LambdaExpression,所以有很多属性方法也可以用。

C#表达式树基础教程

Body 获取 lambda 表达式的主体。
CanReduce 指示可将节点简化为更简单的节点。 如果返回 true,则可以调用 Reduce() 以生成简化形式。
Name 获取 lambda 表达式的名称。
NodeType 返回此 Expression 的节点类型。
Parameters 获取 lambda 表达式的参数。
ReturnType 获取 lambda 表达式的返回类型。
TailCall 获取一个值,该值指示是否将通过尾调用优化来编译 lambda 表达式。
Type 获取此 Expression 表示的表达式的静态类型。

好了,以上权当小笔记,备忘,目前先用不上,后面慢慢来使用。

解析/执行表达式树

创建表达式树后,就要执行表达式树。

在此之前,你需要了解 委托 Delegate,Func,Action,以及他们中间的关系。

执行表达式树是这样子的

?
1
2
3
Expression<Func<int, int, int, int, int>> func = Expression.Lambda<Func<int, int, int, int, int>>(result, a, b, c, d);
var com = func.Compile();
var runRasult = com(12, 12, 13, 13);

func 只是一个表达式树,我们把表达式树构建好后,“要将表达式树转为代码”,使用

.Compile() 方法,可以将表达式树生成一个 委托(例如上面的 com)。

为了简洁上面使用了 var,实际上是这样的

?
1
Func<int,int,int,int,int> com = func.Compile();

四个参数,一个返回值。

?
1
var runRasult = com(12, 12, 13, 13);

C#里有语法糖,对委托可以这样写

?
1
2
3
Expression<Func<int, int, int, int, int>> func = Expression.Lambda<Func<int, int, int, int, int>>(result, a, b, c, d);
 
int runRasult = func.Compile()(12, 12, 13, 13);

以后后面都是这样写了,能够缩成一行的代码,就没必要写出两行。

在 Vs 里面调试和查看表达式树,可以看这里

https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/expression-trees/debugging-expression-trees-in-visual-studio

到此这篇关于C#表达式树基础教程的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://www.cnblogs.com/whuanle/p/11562372.html

延伸 · 阅读

精彩推荐
  • C#Unity实现简单摇杆的制作

    Unity实现简单摇杆的制作

    这篇文章主要为大家详细介绍了Unity实现简单摇杆的制作,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    Zero_LJ6072022-12-05
  • C#C#导入导出Excel数据的两种方法

    C#导入导出Excel数据的两种方法

    这篇文章主要为大家详细介绍了C#导入导出Excel数据的两种方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    路博林9992021-12-29
  • C#C# 实现在当前目录基础上找到上一层目录

    C# 实现在当前目录基础上找到上一层目录

    这篇文章主要介绍了C# 实现在当前目录基础上找到上一层目录,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    creay_king4492022-10-27
  • C#Unity Shader实现描边OutLine效果

    Unity Shader实现描边OutLine效果

    这篇文章主要为大家详细介绍了Unity Shader实现描边OutLine效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    elegentbeauty7062022-08-20
  • C#C#微信接口之推送模板消息功能示例

    C#微信接口之推送模板消息功能示例

    这篇文章主要介绍了C#微信接口之推送模板消息功能,结合实例形式分析了C#操作微信推送模板消息接口的具体操作步骤与相关使用技巧,需要的朋友可以参考...

    兰給3622022-01-12
  • C#c# winform异步不卡界面的实现方法

    c# winform异步不卡界面的实现方法

    这篇文章主要给大家介绍了关于c# winform异步不卡界面的实现方法,文中通过示例代码介绍的非常详细,对大家学习或者使用c#具有一定的参考学习价值,需...

    爱码爱生活4352022-07-28
  • C#C#实现关闭子窗口而不释放子窗口对象的方法

    C#实现关闭子窗口而不释放子窗口对象的方法

    下面小编就为大家带来一篇C#实现关闭子窗口而不释放子窗口对象的方法 。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来...

    C#教程网12172021-12-20
  • C#C#构建分页应用的方法分析

    C#构建分页应用的方法分析

    这篇文章主要介绍了C#构建分页应用的方法,结合实例形式分析了C#创建分页功能的具体步骤与相关实现技巧,需要的朋友可以参考下...

    pan_junbiao12412021-12-21