C# 表达式树 Expression

表达式树是定义代码的数据结构。 它们基于编译器用于分析代码和生成已编译输出的相同结构。

几种常见的表达式

BinaryExpression 包含二元运算符的表达式

 1                 BinaryExpression binaryExpression = Expression.MakeBinary(ExpressionType.Add,Expression.Constant(1),Expression.Constant(2));
 2                 Console.WriteLine(binaryExpression.ToString());//(1+2) 不进行溢出检查
 3                 binaryExpression = Expression.MakeBinary(ExpressionType.AddChecked, Expression.Constant(3), Expression.Constant(4));
 4                 Console.WriteLine(binaryExpression.ToString());//(3+4) 进行溢出检查
 5                 binaryExpression = Expression.MakeBinary(ExpressionType.Subtract, Expression.Constant(5), Expression.Constant(6));
 6                 Console.WriteLine(binaryExpression.ToString());//(5-6) 不进行溢出检查
 7                 binaryExpression = Expression.MakeBinary(ExpressionType.SubtractChecked, Expression.Constant(7), Expression.Constant(8));
 8                 Console.WriteLine(binaryExpression.ToString());//(7-8) 进行溢出检查
 9                 binaryExpression = Expression.MakeBinary(ExpressionType.Multiply, Expression.Constant(9), Expression.Constant(10));
10                 Console.WriteLine(binaryExpression.ToString());//(9*10) 不进行溢出检查
11                 binaryExpression = Expression.MakeBinary(ExpressionType.MultiplyChecked, Expression.Constant(11), Expression.Constant(12));
12                 Console.WriteLine(binaryExpression.ToString());//(11*12) 进行溢出检查
13                 binaryExpression = Expression.MakeBinary(ExpressionType.Divide, Expression.Constant(13), Expression.Constant(14));
14                 Console.WriteLine(binaryExpression.ToString());//(13/14)
15                 binaryExpression = Expression.MakeBinary(ExpressionType.Modulo, Expression.Constant(15), Expression.Constant(16));
16                 Console.WriteLine(binaryExpression.ToString());//(15%16) 

BlockExpression 包含一个表达式序列的块,表达式中可定义变量

 1                 BlockExpression blockExpr = Expression.Block(
 2                      Expression.Call(null, typeof(Console).GetMethod("Write", new Type[] { typeof(String) }), Expression.Constant("Hello ")),
 3                      Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }), Expression.Constant("World!")),
 4                      Expression.Constant(42)
 5                 );
 6                 var result = Expression.Lambda<Func<int>>(blockExpr).Compile()();
 7                 Console.WriteLine("**************************");
 8                 foreach (var expr in blockExpr.Expressions)
 9                     Console.WriteLine(expr.ToString());
10                 Console.WriteLine("**************************");
11                 Console.WriteLine(result);

程序执行结果

ConditionalExpression 具有条件运算符的表达式

Expression conditionExpr = Expression.Condition(Expression.Constant(num > 10),Expression.Constant("num is greater than 10"),Expression.Constant("num is smaller than 10"));

ConstantExpression 具有常数值的表达式

1 Expression.Constant(5.5);
2 Expression.Constant("Hello World!");

DefaultExpression 类型或空表达式的默认值

1                 Expression defaultExpr = Expression.Default(typeof(byte));
2
3                 // Print out the expression.
4                 Console.WriteLine(defaultExpr.ToString());//  等价于 default(byte)
5
6                 // The following statement first creates an expression tree,
7                 // then compiles it, and then executes it.
8                 Console.WriteLine(Expression.Lambda<Func<byte>>(defaultExpr).Compile()());//0

ParameterExpression 命名的参数表达式

ParameterExpression param = Expression.Parameter(typeof(int));

IndexExpression 编制属性或数组的索引

1                 ParameterExpression arrayExpr = Expression.Parameter(typeof(int[]), "Array");
2                 ParameterExpression indexExpr = Expression.Parameter(typeof(int), "Index");
3                 ParameterExpression valueExpr = Expression.Parameter(typeof(int), "Value");
4                 Expression arrayAccessExpr = Expression.ArrayAccess(
5                     arrayExpr,
6                     indexExpr
7                 );//Array[Index]

InvocationExpression 将委托或 lambda 表达式应用于参数表达式列表的表达式

1                 Expression<Func<int, int, bool>> largeSumTest =(num1, num2) => (num1 + num2) > 1000;
2                 InvocationExpression invocationExpression =Expression.Invoke(largeSumTest,Expression.Constant(539),Expression.Constant(281));
3                 Console.WriteLine(invocationExpression.ToString());//Invoke((num1, num2) => ((num1 + num2) > 1000), 539, 281)

LambdaExpression 描述一个 lambda 表达式。 这将捕获与 .NET 方法体类似的代码块

1                 ParameterExpression paramExpr = Expression.Parameter(typeof(int), "arg");
2                 LambdaExpression lambdaExpr = Expression.Lambda(Expression.Add(paramExpr,Expression.Constant(1)),new List<ParameterExpression>() { paramExpr });
3                 Console.WriteLine(lambdaExpr);// arg => (arg +1)

ElementInit   表示 IEnumerable 集合的单个元素的初始值设定项

ListInitExpression 表示包含集合初始值设定项的构造函数调用

NewExpression 构造函数调用

 1                 string tree1 = "maple";
 2                 string tree2 = "oak";
 3
 4                 MethodInfo addMethod = typeof(Dictionary<int, string>).GetMethod("Add");
 5
 6                 // Create two ElementInit objects that represent the
 7                 // two key-value pairs to add to the Dictionary.
 8                 ElementInit elementInit1 =Expression.ElementInit(addMethod,Expression.Constant(tree1.Length),Expression.Constant(tree1));
 9                 ElementInit elementInit2 =Expression.ElementInit(addMethod,Expression.Constant(tree2.Length),Expression.Constant(tree2));
10
11                 // Create a NewExpression that represents constructing
12                 // a new instance of Dictionary<int, string>.
13                 NewExpression newDictionaryExpression = Expression.New(typeof(Dictionary<int, string>));//等价 new Dictionary<int, string>();
14
15                 // Create a ListInitExpression that represents initializing
16                 // a new Dictionary<> instance with two key-value pairs.
17                 ListInitExpression listInitExpression = Expression.ListInit(newDictionaryExpression, elementInit1, elementInit2);//等价 var dic= new Dictionary<int, string>{}; dic.Add(5,"maple");dic.Add(3,"oak");
18
19                 Console.WriteLine(listInitExpression.ToString());

LoopExpression 无限循环。 可以使用“break”退出它

LabelTarget  表示 GotoExpression 的目标

 1                 ParameterExpression value = Expression.Parameter(typeof(int), "value");
 2                 ParameterExpression result = Expression.Parameter(typeof(int), "result");
 3                 LabelTarget label = Expression.Label(typeof(int));
 4                 BlockExpression block = Expression.Block(
 5                     new[] { result },
 6                     Expression.Assign(result, Expression.Constant(1)),
 7                         Expression.Loop(
 8                            Expression.IfThenElse(
 9                                Expression.GreaterThan(value, Expression.Constant(1)),
10                                Expression.MultiplyAssign(result,
11                                    Expression.PostDecrementAssign(value)),
12                                Expression.Break(label, result)
13                            ),
14                        label
15                     )
16                 );
17                 //var s =value=>
18                 //{
19                 //    var result = 1;
20                 //    for (int i = value; i >1; i--)
21                 //    {
22                 //        result *= i;
23                 //    }
24                 //    return result;
25                 //};

MemberAssignment 针对对象的字段或属性的赋值运算

MemberBinding 提供一种基类,该基类派生表示绑定的类,这些绑定用于初始化新创建对象的成员

MemberExpression 访问字段或属性

MemberInitExpression 调用构造函数并初始化新对象的一个或多个成员

MemberListBinding 初始化新创建对象的集合成员的元素

MemberMemberBinding 初始化新创建对象的成员的成员

 1     public class BaseEntity
 2     {
 3         /// <summary>
 4         /// 创建人账号
 5         /// </summary>
 6         [DataMember]
 7         [Display(Name = "创建人账号")]
 8         [Column]
 9         public string CreateMan { get; set; }
10         /// <summary>
11         /// 创建时间
12         /// </summary>
13         [DataMember]
14         [Display(Name = "创建时间")]
15         public DateTime CreateDateTime { get; set; }
16         /// <summary>
17         /// 异动人账号
18         /// </summary>
19         [DataMember]
20         [Display(Name = "异动人账号")]
21         public string TrMan { get; set; }
22         /// <summary>
23         /// 异动时间
24         /// </summary>
25         [DataMember]
26         [Display(Name = "异动时间")]
27         public DateTime TrDateTime { get; set; }
28         /// <summary>
29         /// 时间戳
30         /// </summary>
31         [DataMember]
32         [Display(Name = "时间戳")]
33         public DateTime? TrVersion { get; set; }
34     }

 1                 BaseEntity entity = new BaseEntity();
 2                 NewExpression newExp = Expression.New(typeof(BaseEntity));
 3
 4                 MemberInfo createMan = typeof(BaseEntity).GetMember("CreateMan")[0];
 5                 MemberInfo trMan = typeof(BaseEntity).GetMember("TrMan")[0];
 6                 MemberBinding createManMemberBinding = Expression.Bind(createMan, Expression.Constant("horse"));
 7                 MemberBinding trManMemberBinding = Expression.Bind(trMan, Expression.Constant("admin"));
 8                 MemberInitExpression memberInitExpression = Expression.MemberInit(newExp, createManMemberBinding, trManMemberBinding);
 9
10                 Console.WriteLine(memberInitExpression.ToString());

NewArrayExpression 创建新数组并可能初始化该新数组的元素

 1                 List<Expression> trees =new List<Expression>()
 2                 {
 3                     Expression.Constant("oak"),
 4                     Expression.Constant("fir"),
 5                     Expression.Constant("spruce"),
 6                     Expression.Constant("alder")
 7                 };
 8                 NewArrayExpression newArrayExpression =Expression.NewArrayInit(typeof(string), trees);
 9
10                 // new [] {"oak", "fir", "spruce", "alder"}
11                 Console.WriteLine(newArrayExpression.ToString());

SwitchCase  SwitchExpression 的一个事例

SwitchExpression 一个控制表达式,该表达式通过将控制传递到 SwitchCase 来处理多重选择

1                 ConstantExpression switchValue = Expression.Constant(2);
2                 SwitchExpression switchExpr =Expression.Switch(switchValue,new SwitchCase[] {
3                     Expression.SwitchCase(Expression.Call(null,
4                     typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }),
5                     Expression.Constant("First")),Expression.Constant(1)),
6                     Expression.SwitchCase(Expression.Call(null,
7                     typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }),
8                     Expression.Constant("Second")),Expression.Constant(2))});
9                 Expression.Lambda<Action>(switchExpr).Compile()();

TryExpression  try/catch/finally/fault 块

CatchBlock  try 块中的 catch 语句

1                     TryExpression tryCatchExpr =Expression.TryCatch(
2                     Expression.Block(
3                         Expression.Throw(Expression.Constant(new DivideByZeroException())),
4                         Expression.Constant("Try block")
5                     ),
6                     Expression.Catch(
7                         typeof(DivideByZeroException),
8                         Expression.Constant("Catch block")
9                 ));

UnaryExpression 包含一元运算符的表达式

UnaryExpression typeAsExpression =Expression.TypeAs(Expression.Constant(34, typeof(int)),typeof(int?));//等价    34 as int?;

微软文档地址:

System.Linq.Expressions:https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.expressions?view=netframework-4.8

ExpressionType:https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.expressions.expressiontype?view=netframework-4.8#System_Linq_Expressions_ExpressionType_Add

原文地址:https://www.cnblogs.com/Dewumu/p/11760686.html

时间: 2024-10-21 19:11:25

C# 表达式树 Expression的相关文章

[C#] 说说表达式树 - Expression Trees

说说表达式树 - Expression Trees 序 简单说下表达式树. 目录 介绍 表达式树以树形数据结构表示代码,其中每一个节点都是一种表达式,比如方法调用和 x < y 这样的二元运算等. 你可以对表达式树中的代码进行编辑和运算.这样能够动态修改可执行代码.在不同数据库中执行 LINQ 查询以及创建动态查询. 表达式树还能用于动态语言运行时 (DLR) 以提供动态语言和 .NET Framework 之间的互操作性,同时保证编译器编写员能够发射表达式树而非 Microsoft 中间语言

表达式树 Expression

转载泛型方法动态生成表达式树 Expression public string GetGridJSON(TraderInfo model) { IQueryable<TraderInfo> Temp = db.TraderInfo; if (model.LoginAccount != null) { Temp = Temp.Where(X => X.LoginAccount == model.LoginAccount); } if (model.ShopName != null) { T

[C#] C# 知识回顾 - 表达式树 Expression Trees

C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达式树 调试 简介 表达式树以树形数据结构表示代码,其中每一个节点都是一种表达式,比如方法调用和 x < y 这样的二元运算等. 你可以对表达式树中的代码进行编辑和运算.这样能够动态修改可执行代码.在不同数据库中执行 LINQ 查询以及创建动态查询. 表达式树还能用于动态语言运行时 (DLR) 以提供

泛型方法动态生成表达式树 Expression

public string GetGridJSON(TraderInfo model) { IQueryable<TraderInfo> Temp = db.TraderInfo; if (model.LoginAccount != null) { Temp = Temp.Where(X => X.LoginAccount == model.LoginAccount); } if (model.ShopName != null) { Temp = Temp.Where(X => X

Expression表达式树

表达式树表示树状数据结构的代码,树状结构中的每个节点都是一个表达式,例如一个方法调用或类似 x < y 的二元运算 1.利用 Lambda 表达式创建表达式树 Expression<Func<int, int, int, int>> expr = (x, y, z) => (x + y) / z; 2.编译表达式树,该方法将表达式树表示的代码编译成一个可执行委托 expr.Compile()(1, 2, 3) 3.IQueryable<T>的扩展方法,Whe

[.net 面向对象程序设计进阶] (5) Lamda表达式(二) 表达式树快速入门

[.net 面向对象程序设计进阶] (6) Lamda表达式(二) 表达式树快速入门 本节导读: 认识表达式树(Expression Tree),学习使用Lambda创建表达式树,解析表达式树. 学习表达式在程序设计中的优点:比如构造动态查询.动态构造表达式树完成未知对象属性访问,比反射的性能高出很多.我们可以说表达式树才是Lambda的精髓,是我们必须要熟练掌握并灵活运用的. 1.关于表达式树(Expression Tree) 表达式树以树形数据结构表示代码,其中每一个节点都是一种表达式,比如

Lambda表达式和表达式树

在C# 2.0中,通过方法组转换和匿名方法,使委托的实现得到了极大的简化.但是,匿名方法仍然有些臃肿,而且当代码中充满了匿名方法的时候,可读性可能就会受到影响.C# 3.0中出现的Lambda表达式在不牺牲可读性的前提下,进一步简化了委托. LINQ的基本功能就是创建操作管道,以及这些操作需要的任何状态.这些操作表示了各种关于数据的逻辑,例如数据筛选,数据排序等等.通常这些操作都是用委托来表示.Lambda表达式是对LINQ数据操作的一种符合语言习惯的表示方式. Lambda表达式不仅可以用来创

什么是表达式树,它与表达式、委托有什么区别?

序言 首先,需要普及下基础知识: Expression我们称之为:表达式树, 而Func<>或者Action 称之为:匿名委托,Func与Action的区别是Func带返回值(至少一个参数),Action不带返回值(可以没有任何参数). 以上的关键词是在.net 3.5之后出现的,配合Linq中Lambda使用. 当然Expression还可以动态的进行构造它,而不使用Lambda表达式来定义. 什么是表达式树 它是一种数据结构体,用于存储需要计算.运算的一种结构.这种结构可以只是”存储“,而

Lambda表达式和Lambda表达式树

LINQ的基本功能就是创建操作管道,以及这些操作需要的任何状态. 为了富有效率的使用数据库和其他查询引擎,我们需要一种不同的方式表示管道中的各个操作.即把代码当作可在编程中进行检查的数据. Lambda表达式不仅可以用他们创建委托实例,而且C#编译器也能将他们转换成表达式树——用于表示Lambda表达式逻辑的一种数据结构.简言之——Lambda表达式用符号语言习惯的方法来表示LINQ数据管线中的操作. 作为委托的Lambda表达式 Lambda有特殊转换规则:表达式的类型本身并非委托类型,但它可