表達式樹是定義代碼的數據結構。 它們基於編譯器用於分析代碼和生成已編譯輸出的相同結構。
幾種常見的表達式
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