表达式树是定义代码的数据结构。 它们基于编译器用于分析代码和生成已编译输出的相同结构。
几种常见的表达式
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
原文出处:https://www.cnblogs.com/Dewumu/p/11760686.html
来源:oschina
链接:https://my.oschina.net/u/4319036/blog/3248786