反射与表达式树的应用实列

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()生成委托
            Expression<Func<int>> lambdaExp = Expression.Lambda<Func<int>>(exp123);
            Console.WriteLine(lambdaExp.Compile()());

            ////2.对于比较简单的(不能有赋值、代码块)表达式,可以直接使用lambd表达式
            Expression<Func<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<Func<int>> lambdBlock = Expression.Lambda<Func<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<Func<int, bool>> lambda = Expression.Lambda<Func<int, bool>>(bExpression, pExpression); //lambda 表达式:num => num == 0
            Console.WriteLine(lambda.Compile()(12));

            //5.表达式与反射应用
            //请用表示式实现一个动态逻辑,可以更新任意一种数据实体类的集合,比如list<book>中每一个元素的指定属性;

            Book b1 = new Book() { Author = "1", Name = "zahngsna" };
            List<Book> list_book = new List<Book>();
            for (int i = 0; i < 1000000; i++)
            {
                list_book.Add(b1);
            }

            var sw = new Stopwatch();
            sw.Start();
            ////表达式优化
            SetAllProperty_Exp<Book, string>(list_book, "Author", "123");
            sw.Stop();
            Console.WriteLine("表达式优化耗时:" + sw.ElapsedMilliseconds);
            sw.Restart();
            ////反射
            SetAllProperty<Book>(list_book, "Author", "458");
            sw.Stop();
            Console.WriteLine("反射耗时:" + sw.ElapsedMilliseconds);
          

            //6. 思考题a. xy+x+y
            //法一
            Expression<Func<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<Func<int, int, int>> lambdExp1 = Expression.Lambda<Func<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<Action<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<Action<string>>(bodyExp, parameterExp);
            lambdexp.Compile()("h12");
            Console.ReadKey();

        }

        class Book
        {
            public string Author { get; set; }
            public string Name { get; set; }
        }

        static void SetAllProperty<T>(List<T> 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<T,K>(List<T> 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<Action<T, K>>(setMethodExp, invokeObjExpr, properytValuExp);
            var del = lambdaExp.Compile();
            foreach (T t in list)
            {
               // propertyInfo.SetValue(t,propertyValue,null);
                del(t, propertyValue);
            }
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/ZHXI/p/12888230.html