using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace 表达式树 { class Program { static void Main(string[] args) { //1.构建简单的表达式树 //1+2+3 var EXP1 = Expression.Constant(1); var exp2 = Expression.Constant(2); var exp12 = Expression.Add(EXP1, exp2); var exp3 = Expression.Constant(3); var exp123 = Expression.Add(exp12, exp3); ////转换成lambda表达式才能调用compile()生成委托 Expressionint>> lambdaExp = Expression.Lambda int>>(exp123); Console.WriteLine(lambdaExp.Compile()()); ////2.对于比较简单的(不能有赋值、代码块)表达式,可以直接使用lambd表达式 Expression int>> lambdExp = () => 1 + 2 + 3; Console.WriteLine(lambdaExp.Compile()()); //3.代码块表达式 //static int HelloWorld() //{ // Console.Write("Hello World!"); // return 42; //} BlockExpression blockExp = Expression.Block ( Expression.Call ( null, typeof(Console).GetMethod("Write", new[] { typeof(string) }), Expression.Constant("Hello World") ), Expression.Constant(42) ); Expression int>> lambdBlock = Expression.Lambda int>>(blockExp); Console.WriteLine(lambdBlock.Compile()()); //4.通过 Expression 类创建表达式树 // lambda:num => num == 0 ParameterExpression pExpression = Expression.Parameter(typeof(int),"num"); //参数:num ConstantExpression cExpression = Expression.Constant(0); //常量:0 //BinaryExpression bExpression = Expression.MakeBinary(ExpressionType.Equal, pExpression, cExpression); //表达式:num == 0 BinaryExpression bExpression= Expression.Equal(pExpression, cExpression); Expression int, bool>> lambda = Expression.Lambda int, bool>>(bExpression, pExpression); //lambda 表达式:num => num == 0 Console.WriteLine(lambda.Compile()(12)); //5.表达式与反射应用 //请用表示式实现一个动态逻辑,可以更新任意一种数据实体类的集合,比如list 中每一个元素的指定属性; Book b1 = new Book() { Author = "1", Name = "zahngsna" }; Listlist_book = new List (); for (int i = 0; i < 1000000; i++) { list_book.Add(b1); } var sw = new Stopwatch(); sw.Start(); ////表达式优化 SetAllProperty_Exp string>(list_book, "Author", "123"); sw.Stop(); Console.WriteLine("表达式优化耗时:" + sw.ElapsedMilliseconds); sw.Restart(); ////反射 SetAllProperty (list_book, "Author", "458"); sw.Stop(); Console.WriteLine("反射耗时:" + sw.ElapsedMilliseconds); //6. 思考题a. xy+x+y //法一 Expression int, int, int>> lambdEx = (x, y) => x * y + x + y; Console.WriteLine("表达式:" + lambdEx + ",值:" + lambdEx.Compile()(1, 2)); ////法二 var xExp = Expression.Parameter(typeof(int), "x"); var yExp = Expression.Parameter(typeof(int), "y"); var xyExp = Expression.Multiply(xExp, yExp); var xplusyExp = Expression.Add(xExp, yExp); var exp = Expression.Add(xyExp, xplusyExp); Expression int, int, int>> lambdExp1 = Expression.Lambda int, int, int>>(exp, new[] { xExp, yExp }); Func<int, int, int> del = lambdExp1.Compile(); Console.WriteLine("表达式:" + lambdExp1 + ",值:" + del(1, 2)); // 思考题b. Console.WriteLine("hi") //法一 Expression string>> lambdExp2 = (h) => Console.WriteLine(h); lambdExp2.Compile()("hi"); Console.WriteLine(lambdExp2); //法二 var parameterExp = Expression.Parameter(typeof(string), "h"); var methodInfo = typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }); var bodyExp = Expression.Call(null, methodInfo, parameterExp); var lambdexp = Expression.Lambda string>>(bodyExp, parameterExp); lambdexp.Compile()("h12"); Console.ReadKey(); } class Book { public string Author { get; set; } public string Name { get; set; } } static void SetAllProperty (List list, string propertyName, object propertyValue) { var _type = typeof(T); PropertyInfo propertyInfo = _type.GetProperty(propertyName); foreach (T t in list) { propertyInfo.SetValue(t,propertyValue,null); } } static void SetAllProperty_Exp (List list,string propertyName,K propertyValue) { var _type = typeof(T); PropertyInfo propertyInfo = _type.GetProperty(propertyName); var methodInfo = propertyInfo.GetSetMethod(); //参数t var invokeObjExpr = Expression.Parameter(typeof(T), "t"); //参数propertyValue var properytValuExp = Expression.Parameter(propertyInfo.PropertyType, "propertyValue"); //主体方法 var setMethodExp = Expression.Call(invokeObjExpr, methodInfo, properytValuExp); //强类型的委托 var lambdaExp = Expression.Lambda >(setMethodExp, invokeObjExpr, properytValuExp); var del = lambdaExp.Compile(); foreach (T t in list) { // propertyInfo.SetValue(t,propertyValue,null); del(t, propertyValue); } } } }