public static void Show() { { Func <int, int, int> func = (m, n) => m * n + 2; // new Func<int, int, int>((m, n) => m * n + 2); Expression <Func <int, int, int> > exp = (m, n) => m * n + 2; //lambda表达式声明表达式目录树 //Expression<Func<int, int, int>> exp1 = (m, n) =>//只能一行 不能有大括号 // { // return m * n + 2; // }; //Queryable //a=>a.Id>3 //表达式目录树:语法树,或者说是一种数据结构;可以被我们解析 int iResult1 = func.Invoke(12, 23); int iResult2 = exp.Compile().Invoke(12, 23);//可以转换过去 } { Expression <Func <int, int, int> > exp = (m, n) => m * n + 2; ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "m"); ParameterExpression parameterExpression2 = Expression.Parameter(typeof(int), "n"); var multiply = Expression.Multiply(parameterExpression, parameterExpression2); var constant = Expression.Constant(2, typeof(int)); var add = Expression.Add(multiply, constant); Expression <Func <int, int, int> > expression = Expression.Lambda <Func <int, int, int> >( add, new ParameterExpression[] { parameterExpression, parameterExpression2 }); int iResult1 = exp.Compile().Invoke(11, 12); int iResult2 = expression.Compile().Invoke(11, 12); } //自己拼装表达式目录树 { //常量 ConstantExpression conLeft = Expression.Constant(345); ConstantExpression conRight = Expression.Constant(456); BinaryExpression binary = Expression.Add(conLeft, conRight); //345+456 Expression <Action> actExpression = Expression.Lambda <Action>(binary, null); //()=>345+456 //只能执行表示Lambda表达式的表达式目录树,即LambdaExpression或者Expression<TDelegate>类型。如果表达式目录树不是表示Lambda表达式,需要调用Lambda方法创建一个新的表达式 actExpression.Compile()(); //()=>345+456 } { ParameterExpression paraLeft = Expression.Parameter(typeof(int), "a"); //左边 ParameterExpression paraRight = Expression.Parameter(typeof(int), "b"); //右边 BinaryExpression binaryLeft = Expression.Multiply(paraLeft, paraRight); //a*b ConstantExpression conRight = Expression.Constant(2, typeof(int)); //右边常量 BinaryExpression binaryBody = Expression.Add(binaryLeft, conRight); //a*b+2 Expression <Func <int, int, int> > lambda = Expression.Lambda <Func <int, int, int> >(binaryBody, paraLeft, paraRight); Func <int, int, int> func = lambda.Compile();//Expression Compile成委托 int result = func(3, 4); } { Expression <Func <People, bool> > lambda = x => x.Id.ToString().Equals("5"); ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "x"); var field = Expression.Field(parameterExpression, typeof(People).GetField("Id")); var toString = typeof(People).GetMethod("ToString"); var toStringCall = Expression.Call(field, toString, new Expression[0]); var equals = typeof(People).GetMethod("Equals"); var constant = Expression.Constant("5", typeof(string)); var equalsCall = Expression.Call(toStringCall, equals, new Expression[] { constant }); Expression <Func <People, bool> > expression = Expression.Lambda <Func <People, bool> >(equalsCall, new ParameterExpression[] { parameterExpression }); expression.Compile().Invoke(new People() { Id = 11, Name = "Eleven", Age = 31 }); } { ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "x"); Expression field = Expression.Field(parameterExpression, typeof(People).GetField("Id")); MethodCallExpression toString = Expression.Call(field, typeof(People).GetMethod("ToString"), new Expression[0]); ConstantExpression constantExpression = Expression.Constant("5", typeof(string)); MethodCallExpression equals = Expression.Call(toString, typeof(People).GetMethod("Equals"), new Expression[] { constantExpression }); Expression <Func <People, bool> > lambda = Expression.Lambda <Func <People, bool> >(equals, new ParameterExpression[] { parameterExpression }); bool bResult = lambda.Compile()(new People() { Id = 11, Name = "Eleven", Age = 31 }); } { //以前根据用户输入拼装条件 string sql = "SELECT * FROM USER WHERE 1=1"; string name = "Eleven";//用户选择条件 if (string.IsNullOrWhiteSpace(name)) { sql += $" and name like '%{name}%'";//应该参数化 } //现在entityx framework查询的时候,需要一个表达式目录树 IQueryable <int> list = null; //都不过滤 1 if (true)//只过滤A 2 { //list=list.Where(); Expression <Func <People, bool> > exp1 = x => x.Id > 1; } if (true)//只过滤B 3 { //list=list.Where(); Expression <Func <People, bool> > exp2 = x => x.Age > 10; } //都过滤 4 Expression <Func <People, bool> > exp3 = x => x.Id > 1 && x.Age > 10; //2个条件 4种可能 排列组合 //3个条件 2的3次方 //list.Where() //拼装表达式目录树,交给下端用 //Expression<Func<People, bool>> lambda = x => x.Age > 5; ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "x"); Expression propertyExpression = Expression.Property(parameterExpression, typeof(People).GetProperty("Age")); //Expression property = Expression.Field(parameterExpression, typeof(People).GetField("Id")); ConstantExpression constantExpression = Expression.Constant(5, typeof(int)); BinaryExpression binary = Expression.GreaterThan(propertyExpression, constantExpression);//添加方法的 Expression <Func <People, bool> > lambda = Expression.Lambda <Func <People, bool> >(binary, new ParameterExpression[] { parameterExpression }); bool bResult = lambda.Compile()(new People() { Id = 11, Name = "Eleven", Age = 31 }); } { People people = new People() { Id = 11, Name = "Eleven", Age = 31 }; PeopleCopy peopleCopy = new PeopleCopy() { Id = people.Id, Name = people.Name, Age = people.Age }; //硬编码 是不是写死了 只能为这两个类型服务 性能是最好的 { //反射 不同类型都能实现 var result = ReflectionMapper.Trans <People, PeopleCopy>(people); } { //序列化器 不同类型都能实现 var result = SerializeMapper.Trans <People, PeopleCopy>(people); } { //1 通用 2 性能要高 //能不能动态的生成硬编码,缓存起来 var result = ExpressionMapper.Trans <People, PeopleCopy>(people); } { var result = ExpressionMapper.Trans <People, PeopleCopy>(people); } { var result = ExpressionGenericMapper <People, PeopleCopy> .Trans(people); } { var result = ExpressionGenericMapper <People, PeopleCopy> .Trans(people); } //总结表达式目录树动态生成的用途了: //可以用来替代反射,因为反射可以通用,但是性能不够 //生成硬编码,可以提升性能 //automapper基于emit 动态生成硬编码 //Expression<Func<People, PeopleCopy>> lambda = p => // new PeopleCopy() // { // Id = p.Id, // Name = p.Name, // Age = p.Age // }; //lambda.Compile()(people); ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "p"); List <MemberBinding> memberBindingList = new List <MemberBinding>(); foreach (var item in typeof(PeopleCopy).GetProperties()) { MemberExpression property = Expression.Property(parameterExpression, typeof(People).GetProperty(item.Name)); MemberBinding memberBinding = Expression.Bind(item, property); memberBindingList.Add(memberBinding); } foreach (var item in typeof(PeopleCopy).GetFields()) { MemberExpression property = Expression.Field(parameterExpression, typeof(People).GetField(item.Name)); MemberBinding memberBinding = Expression.Bind(item, property); memberBindingList.Add(memberBinding); } MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(PeopleCopy)), memberBindingList.ToArray()); Expression <Func <People, PeopleCopy> > lambda = Expression.Lambda <Func <People, PeopleCopy> >(memberInitExpression, new ParameterExpression[] { parameterExpression }); Func <People, PeopleCopy> func = lambda.Compile(); PeopleCopy copy = func(people); } }
public static void MapperTest() { People people = new People() { Id = 11, Name = "Eleven", Age = 31 }; long common = 0; long generic = 0; long cache = 0; long reflection = 0; long serialize = 0; { Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < 1000000; i++) { PeopleCopy peopleCopy = new PeopleCopy() { Id = people.Id, Name = people.Name, Age = people.Age }; } watch.Stop(); common = watch.ElapsedMilliseconds; } { Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < 1000000; i++) { PeopleCopy peopleCopy = ReflectionMapper.Trans <People, PeopleCopy>(people); } watch.Stop(); reflection = watch.ElapsedMilliseconds; } { Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < 1000000; i++) { PeopleCopy peopleCopy = SerializeMapper.Trans <People, PeopleCopy>(people); } watch.Stop(); serialize = watch.ElapsedMilliseconds; } { Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < 1000000; i++) { PeopleCopy peopleCopy = ExpressionMapper.Trans <People, PeopleCopy>(people); } watch.Stop(); cache = watch.ElapsedMilliseconds; } { Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < 1000000; i++) { PeopleCopy peopleCopy = ExpressionGenericMapper <People, PeopleCopy> .Trans(people); } watch.Stop(); generic = watch.ElapsedMilliseconds; } Console.WriteLine($"common = { common} ms"); Console.WriteLine($"reflection = { reflection} ms"); Console.WriteLine($"serialize = { serialize} ms"); Console.WriteLine($"cache = { cache} ms"); Console.WriteLine($"generic = { generic} ms"); }
public static void Show() { #region MyRegion { Func <int, int, int> func = (m, n) => m * n + 2; func.Invoke(3, 4); //表达式目录树:语法树,一种数据结构 Expression <Func <int, int, int> > exp = (m, n) => m * n + 2; int iResult = exp.Compile()(3, 4); } #endregion #region 拼装表达式目录树 { //拼装表达式目录树 ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "m"); //参数m ParameterExpression parameterExpression2 = Expression.Parameter(typeof(int), "n"); //参数n BinaryExpression binaryExpression = Expression.Multiply(parameterExpression, parameterExpression2); //m*n ConstantExpression constantExpression = Expression.Constant(2, typeof(int)); BinaryExpression addExpression = Expression.Add(binaryExpression, constantExpression); Expression <Func <int, int, int> > exp = Expression.Lambda <Func <int, int, int> >(addExpression, new ParameterExpression[] { parameterExpression, parameterExpression2 }); int iResult = exp.Compile()(3, 4); } #endregion #region 拼装表达式目录树 Expression<Func<People, bool>> lambda = x => x.Age > 5; { //Expression<Func<People, bool>> lambda = x => x.Age > 5; ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "x"); // MemberExpression memberExperssion= Expression.Property(parameterExpression, typeof(People).GetProperty("Age")); MemberExpression memberExperssion = Expression.Field(parameterExpression, typeof(People).GetField("Id")); ConstantExpression constantExpression = Expression.Constant(5, typeof(int)); BinaryExpression binaryExpression = Expression.GreaterThan(memberExperssion, constantExpression); Expression <Func <People, bool> > lambda = Expression.Lambda <Func <People, bool> >(binaryExpression, new ParameterExpression[] { parameterExpression }); bool bResult = lambda.Compile()(new People { Id = 1, Name = "tmo", Age = 23 }); } #endregion #region 拼装表达式目录树 Expression<Func<People, bool>> lambda = x => x.Id.ToString().Equals("5"); { //Expression<Func<People, bool>> lambda = x => x.Id.ToString().Equals("5"); ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "x"); MemberExpression memberExpression = Expression.Field(parameterExpression, typeof(People).GetField("Id")); MethodCallExpression toStringExp = Expression.Call(memberExpression, typeof(People).GetMethod("ToString"), new Expression[0]); MethodCallExpression equalsExp = Expression.Call(toStringExp, typeof(People).GetMethod("Equals"), new Expression[] { Expression.Constant("5", typeof(string)) }); Expression <Func <People, bool> > lambda = Expression.Lambda <Func <People, bool> >(equalsExp, new ParameterExpression[] { parameterExpression }); bool bResult = lambda.Compile()(new People { Id = 1, Name = "tmo", Age = 23 }); } #endregion { People people = new People { Id = 1, Name = "tmo", Age = 23 }; // PeopleCopy peopleCocy = Trans<People, PeopleCopy>(people); Expression <Func <People, PeopleCopy> > lambda = p => new PeopleCopy() { Id = p.Id, Name = p.Name, Age = p.Age }; ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "p"); NewExpression newExpression = Expression.New(typeof(PeopleCopy)); List <MemberBinding> memberBindingList = new List <MemberBinding>(); foreach (var item in typeof(PeopleCopy).GetProperties()) { MemberExpression property = Expression.Property(parameterExpression, typeof(People).GetProperty(item.Name)); MemberBinding memberBinding = Expression.Bind(item, property); memberBindingList.Add(memberBinding); } foreach (var item in typeof(PeopleCopy).GetFields()) { MemberExpression field = Expression.Field(parameterExpression, typeof(People).GetField(item.Name)); MemberBinding memberBinding = Expression.Bind(item, field); memberBindingList.Add(memberBinding); } Expression <Func <People, PeopleCopy> > lambda2 = Expression.Lambda <Func <People, PeopleCopy> >(Expression.MemberInit(newExpression, memberBindingList.ToArray()), new ParameterExpression[] { parameterExpression }); PeopleCopy peopleCocy2 = lambda2.Compile()(people); //PeopleCopy peopleCocy3 = TransExp<People, PeopleCopy>(people); #region 比较反射实现和表达式树实现哪个性能更好 //TaskFactory taskFactory = new TaskFactory(); //for (int i = 0; i < 2; i++) //{ // taskFactory.StartNew(() => // { // }); //} Stopwatch sw = new Stopwatch(); sw.Start(); for (int i = 0; i < 10000000; i++) { Trans <People, PeopleCopy>(people); } sw.Stop(); Console.WriteLine("Trans方法用时:{0}", sw.ElapsedMilliseconds); //sw.Start(); //for (int i = 0; i < 10000000; i++) //{ // TransExp<People, PeopleCopy>(people); //} //sw.Stop(); //Console.WriteLine("TransExp方法用时:{0}", sw.ElapsedMilliseconds); #endregion } }
public static void Show() { { //ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "m"); //ParameterExpression parameterExpression2 = Expression.Parameter(typeof(int), "n"); //var binaryExpression = Expression.Add(Expression.Multiply(parameterExpression, parameterExpression2), Expression.Constant(2, typeof(int))); //Expression<Func<int, int, int>> expression = Expression.Lambda<Func<int, int, int>>(binaryExpression, // new ParameterExpression[] // { // parameterExpression, // parameterExpression2 // }); //expression.Compile(); } { Console.WriteLine("***************Lambda表达式******************"); Func <int, int, int> func = (m, n) => m * n + 2;//Lambda表达式 Console.WriteLine("***************Lambda表达式目录树******************"); Expression <Func <int, int, int> > exp = (m, n) => m * n + 2; //lambda表达式声明 表达式目录树 //Expression<Func<int, int, int>> exp1 = (m, n) => // { // return m * n + 2; // }; Console.WriteLine("***************************************"); //表达式目录树:语法树,或者说是一种数据结构 int iResult1 = func.Invoke(12, 23); int iResult2 = exp.Compile().Invoke(12, 23);//Compile把表达式目录树编译成委托 } //自己拼装表达式目录树 { //常量 ConstantExpression conLeft = Expression.Constant(345); ConstantExpression conRight = Expression.Constant(456); BinaryExpression binary = Expression.Add(conLeft, conRight);//345+456 Expression <Func <int> > actExpression = Expression.Lambda <Func <int> >(binary, null); //只能执行表示Lambda表达式的表达式目录树,即LambdaExpression或者Expression<TDelegate>类型。如果表达式目录树不是表示Lambda表达式,需要调用Lambda方法创建一个新的表达式 Func <int> func = actExpression.Compile(); int iResult = func.Invoke();//()=>345+456 } { // Expression<Func<int, int, int>> exp = (m, n) => m * n + 2; ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "m"); //m ParameterExpression parameterExpression2 = Expression.Parameter(typeof(int), "n"); //n BinaryExpression binaryExpression = Expression.Multiply(parameterExpression, parameterExpression2); //m*n ConstantExpression constantExpression = Expression.Constant(2, typeof(int)); //2 BinaryExpression binaryExpressionAdd = Expression.Add(binaryExpression, constantExpression); //M*N+2 方法体 Expression <Func <int, int, int> > exp = Expression.Lambda <Func <int, int, int> >(binaryExpressionAdd, new ParameterExpression[] //参数列表 { parameterExpression, parameterExpression2 }); int iResult2 = exp.Compile().Invoke(12, 23); } { // Expression<Func<int, int, int>> exp = (m, n) => m * (n + 2); ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "m"); //m ParameterExpression parameterExpression2 = Expression.Parameter(typeof(int), "n"); //n ConstantExpression constantExpression = Expression.Constant(2, typeof(int)); //2 BinaryExpression binaryExpressionAdd = Expression.Add(parameterExpression2, constantExpression); //n+2 BinaryExpression binaryExpressionMutiply = Expression.Multiply(parameterExpression, binaryExpressionAdd); //m * (n + 2) Expression <Func <int, int, int> > exp = Expression.Lambda <Func <int, int, int> >(binaryExpressionMutiply, new ParameterExpression[] //参数列表 { parameterExpression, parameterExpression2 }); int iResult2 = exp.Compile().Invoke(12, 23); } { ////以前根据用户输入拼装条件 //string sql = "SELECT * FROM USER WHERE 1=1"; //string name = Console.ReadLine(); //if (string.IsNullOrWhiteSpace(name))//看有没有输入 //{ // sql += $" and name like '%{name}%'"; //} //if (string.IsNullOrWhiteSpace(name))//看有没有输入 //{ // sql += $" and name like '%{name}%'"; //} //现在entity framework查询的时候,需要一个表达式目录树 IQueryable <int> list = (new List <int>()).AsQueryable(); //if (true)//只过滤A //{ // Expression<Func<int, bool>> exp1 = x => x > 1; //} //if (true)//只过滤B //{ // Expression<Func<int, bool>> exp2 = x => x > 2; //} //if (true)//只过滤C //{ // Expression<Func<int, bool>> exp2 = x => x > 3; //} ////都过滤 //Expression<Func<int, bool>> exp3 = x => x > 1 && x > 2&&x > 3; ////list.ToList(); //有暴露全部数据的危险 //if (true)//只过滤A //{ // //Expression<Func<int, bool>> exp1 = x => x > 1; // list = list.Where(x => x > 1); //} //if (true)//只过滤B //{ // //Expression<Func<int, bool>> exp2 = x => x > 2; // list = list.Where(x => x > 2);//延迟查询 //} //list.Where() //拼装表达式目录树,交给下端用,而不是把集合暴露出来 //Expression<Func<People, bool>> lambda = x => x.Age > 5; ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "x"); Expression propertyExpression = Expression.Property(parameterExpression, typeof(People).GetProperty("Age")); //Expression property = Expression.Field(parameterExpression, typeof(People).GetField("Id")); ConstantExpression constantExpression = Expression.Constant(5, typeof(int)); BinaryExpression binary = Expression.GreaterThan(propertyExpression, constantExpression);//添加方法的 Expression <Func <People, bool> > lambda = Expression.Lambda <Func <People, bool> >(binary, new ParameterExpression[] { parameterExpression }); bool bResult = lambda.Compile()(new People() { Id = 11, Name = "Eleven", Age = 31 }); } { //Expression<Func<People, bool>> lambda = x => x.Id.ToString().Equals("5"); ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "x"); Expression field = Expression.Field(parameterExpression, typeof(People).GetField("Id")); MethodCallExpression toString = Expression.Call(field, typeof(People).GetMethod("ToString"), new Expression[0]); ConstantExpression constantExpression = Expression.Constant("5", typeof(string)); MethodCallExpression equals = Expression.Call(toString, typeof(People).GetMethod("Equals"), new Expression[] { constantExpression }); Expression <Func <People, bool> > lambda = Expression.Lambda <Func <People, bool> >(equals, new ParameterExpression[] { parameterExpression }); bool bResult = lambda.Compile()(new People() { Id = 11, Name = "Eleven", Age = 31 }); } { Console.WriteLine("****************************************"); People people = new People() { Id = 11, Name = "Eleven", Age = 31 }; PeopleCopy peopleCopy = new PeopleCopy() { Id = people.Id, Name = people.Name, Age = people.Age };//硬编码:效率最高 Student--StudentCopy Teacher--teacherCopy //Expression<Func<People, PeopleCopy>> lambda = p => // new PeopleCopy() // { // Id = p.Id, // Name = p.Name, // Age = p.Age // }; //lambda.Compile()(people); ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "p"); List <MemberBinding> memberBindingList = new List <MemberBinding>(); foreach (var item in typeof(PeopleCopy).GetProperties()) { MemberExpression property = Expression.Property(parameterExpression, typeof(People).GetProperty(item.Name)); MemberBinding memberBinding = Expression.Bind(item, property); memberBindingList.Add(memberBinding); } foreach (var item in typeof(PeopleCopy).GetFields()) { MemberExpression property = Expression.Field(parameterExpression, typeof(People).GetField(item.Name)); MemberBinding memberBinding = Expression.Bind(item, property); memberBindingList.Add(memberBinding); } MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(PeopleCopy)), memberBindingList.ToArray()); Expression <Func <People, PeopleCopy> > lambda = Expression.Lambda <Func <People, PeopleCopy> >(memberInitExpression, new ParameterExpression[] { parameterExpression }); Func <People, PeopleCopy> func = lambda.Compile(); PeopleCopy copy = func(people); //ExpressionMapper.Trans<People, PeopleCopy>(people); //ExpressionMapper.Trans<People, PeopleCopy>(people); //ExpressionGenericMapper<People, PeopleCopy>.Trans(people); //ExpressionGenericMapper<People, PeopleCopy>.Trans(people); } }
public static void MapperTest() { { //People people = new People() //{ // Id = 11, // Name = "Richard", // Age = 31 //}; //PeopleCopy peopleCopy = new PeopleCopy()//硬编码 //硬编码性能好,但是通用型差 //{ // Id = people.Id, // Name = people.Name, // Age = people.Age //}; ////如果说有其他别的类型需要转换,那么不是为所有的类型都需要写这样代码? //PeopleCopy peopleCopy1 = ReflectionMapper.Trans<People, PeopleCopy>(people);//反射+泛型方法 //PeopleCopy peopleCopy2 = SerializeMapper.Trans<People, PeopleCopy>(people); ////Func<People, PeopleCopy> exp1 = p => ////{ //// return new PeopleCopy() //// { //// Id = p.Id, //// Name = p.Name, //// Age = p.Age //// }; ////}; ////泛型方法+表达式目录 = 既可以通用,效率高 //PeopleCopy peopleCopy3 = ExpressionMapper.Trans<People, PeopleCopy>(people); //PeopleCopy peopleCopy4 = ExpressionGenericMapper<People, PeopleCopy>.Trans(people); } { Console.WriteLine("****************************性能测试结果***************************"); People people = new People() { Id = 11, Name = "Richard", Age = 31 }; long common = 0; long generic = 0; long cache = 0; long reflection = 0; long serialize = 0; { Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < 100_000; i++) { PeopleCopy peopleCopy = new PeopleCopy() { Id = people.Id, Name = people.Name, Age = people.Age }; } watch.Stop(); common = watch.ElapsedMilliseconds; } { Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < 100_000; i++) { PeopleCopy peopleCopy = ReflectionMapper.Trans <People, PeopleCopy>(people); } watch.Stop(); reflection = watch.ElapsedMilliseconds; } { Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < 100_000; i++) { PeopleCopy peopleCopy = SerializeMapper.Trans <People, PeopleCopy>(people); } watch.Stop(); serialize = watch.ElapsedMilliseconds; } { Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < 100_000; i++) { PeopleCopy peopleCopy = ExpressionMapper.Trans <People, PeopleCopy>(people); } watch.Stop(); cache = watch.ElapsedMilliseconds; } { Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < 100_000; i++) { PeopleCopy peopleCopy = ExpressionGenericMapper <People, PeopleCopy> .Trans(people); } watch.Stop(); generic = watch.ElapsedMilliseconds; } Console.WriteLine($"common = { common} ms"); Console.WriteLine($"reflection = { reflection} ms"); Console.WriteLine($"serialize = { serialize} ms"); Console.WriteLine($"cache = { cache} ms"); Console.WriteLine($"generic = { generic} ms"); } //通过拼接表达式目录树+ 泛型缓存性能最高! //硬编码性能最高,为了通用,动态生成硬编码==最完美 }
public static void Show() { { Func <int, int, int> func = (m, n) => m * 2 + 2; // lambda 只是一个方法 Expression <Func <int, int, int> > exp = (m, n) => m * n + 2; //lambda 表达式声明 表达式目录树 //Expression<Func<int, int, int>> exp1 = (m, n) => // 表达式目录树只能一行,不能有大括号 //{ // return m * n + 2; //}; // 表达式目录树: 语法树, 或者说一种数据结构;可以被我们解析。 int iResult1 = func.Invoke(12, 23); int iResult2 = exp.Compile().Invoke(12, 23); // Compile 之后返回的是一个委托实例 Console.WriteLine(); } { //lambda 写法 Expression <Func <int, int, int> > exp = (m, n) => m * n + 2; // 不用lambda的写法 ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "m"); ParameterExpression parameterExpression2 = Expression.Parameter(typeof(int), "n"); BinaryExpression multiply = Expression.Multiply(parameterExpression, parameterExpression2); ConstantExpression constant = Expression.Constant(2, typeof(int)); BinaryExpression add = Expression.Add(multiply, constant); Expression <Func <int, int, int> > expression = Expression.Lambda <Func <int, int, int> >( add, new ParameterExpression[] { parameterExpression, parameterExpression2 }); } { ConstantExpression conLeft = Expression.Constant(345); ConstantExpression conRight = Expression.Constant(234); BinaryExpression add = Expression.Add(conLeft, conRight); Expression <Action> actExpression = Expression.Lambda <Action>(add, null); // ()=>345 + 456; actExpression.Compile()(); } { Expression <Func <People, bool> > lambda = x => x.Id.ToString().Equals("5"); ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "x"); var field = Expression.Field(parameterExpression, typeof(People).GetField("Id")); var toString = typeof(People).GetMethod("ToString"); var equals = typeof(People).GetMethod("Equals"); var body = Expression.Call( Expression.Call( field, toString, new Expression[0]), equals, new Expression[] { Expression.Constant("5", typeof(string)) }); Expression <Func <People, bool> > expression = Expression.Lambda <Func <People, bool> >( body, new ParameterExpression[] { parameterExpression } ); var result = expression.Compile()(new People() { Id = 5 }); Console.WriteLine(result); } { // 用处1 { string sql = "Select * from user where 1=1"; string name = "ivan"; if (string.IsNullOrWhiteSpace(name)) { sql += $" and name like '%{name}%'"; } } { //现在entity framework查询的时候,都需要一个表达式目录树 IQueryable <int> list = null; if (true) //过滤A { Expression <Func <People, bool> > exp1 = x => x.Id > 1; } if (true) //过滤B { Expression <Func <People, bool> > exp2 = x => x.Age > 10; } // 都过滤 Expression <Func <People, bool> > exp3 = x => x.Age > 10 && x.Id > 1; { // 表达式链接 Expression <Func <People, bool> > lambda1 = x => x.Age > 5; Expression <Func <People, bool> > lambda2 = x => x.Id > 5; Expression <Func <People, bool> > lambda3 = lambda1.And(lambda2); Expression <Func <People, bool> > lambda4 = lambda1.Or(lambda2); Expression <Func <People, bool> > lambda5 = lambda1.Not(); Do1(lambda3); } // Copy People 属性 { { // 写死了 只能为这两种类型服务, 性能最好因为硬编码 People people = new People() { Id = 1, Name = "Ivan", Age = 32 }; PeopleCopy peopleCopy = new PeopleCopy() { Id = people.Id, Name = people.Name, Age = people.Age }; } { // 利用反射: 不同类型都能实现 People people = new People() { Id = 1, Name = "Ivan", Age = 32 }; var result = ReflectionMapper.Trans <People, PeopleCopy>(people); } { People people = new People() { Id = 1, Name = "Ivan", Age = 32 }; //序列化器 var result = SerializeMapper.Trans <People, PeopleCopy>(people); } { People people = new People() { Id = 1, Name = "Ivan", Age = 32 }; //1. 通用 2. 性能要高 // 能不能动态的生成硬编码,缓存起来 Expression <Func <People, PeopleCopy> > lambda = p => new PeopleCopy() { Id = p.Id, Name = p.Name, Age = p.Age }; ExpressionMapper.Trans <People, PeopleCopy>(people); } } } } }
public static void Show() { { Func <int, int, int> func = (m, n) => m * n + 2; Expression <Func <int, int, int> > exp = (m, n) => m * n + 2;//lambda表达式声明表达式目录树 //Expression<Func<int, int, int>> exp1 = (m, n) => // { // return m * n + 2; // }; //表达式目录树:语法树,或者说是一种数据结构 int iResult1 = func.Invoke(12, 23); int iResult2 = exp.Compile().Invoke(12, 23); } { //自己拼装表达式目录树 ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "m"); //m ParameterExpression parameterExpression2 = Expression.Parameter(typeof(int), "n"); //n BinaryExpression binaryExpression = Expression.Multiply(parameterExpression, parameterExpression2); //m*n ConstantExpression constantExpression = Expression.Constant(2, typeof(int)); //2 BinaryExpression binaryExpressionAdd = Expression.Add(binaryExpression, constantExpression); //M*N+2 Expression <Func <int, int, int> > exp = Expression.Lambda <Func <int, int, int> >(binaryExpressionAdd, new ParameterExpression[] { parameterExpression, parameterExpression2 }); int iResult2 = exp.Compile().Invoke(12, 23); } { ParameterExpression paraLeft = Expression.Parameter(typeof(int), "a"); //左边 ParameterExpression paraRight = Expression.Parameter(typeof(int), "b"); //右边 BinaryExpression binaryLeft = Expression.Multiply(paraLeft, paraRight); //a*b ConstantExpression conRight = Expression.Constant(2, typeof(int)); //右边常量 BinaryExpression binaryBody = Expression.Add(binaryLeft, conRight); //a*b+2 //只能执行表示Lambda表达式的表达式目录树,即LambdaExpression或者Expression<TDelegate>类型。如果表达式目录树不是表示Lambda表达式,需要调用Lambda方法创建一个新的表达式 Expression <Func <int, int, int> > lambda = Expression.Lambda <Func <int, int, int> >(binaryBody, paraLeft, paraRight); Func <int, int, int> func = lambda.Compile();//Expression Compile成委托 int result = func(3, 4); } { //常量 ConstantExpression conLeft = Expression.Constant(345); ConstantExpression conRight = Expression.Constant(456); BinaryExpression binary = Expression.Add(conLeft, conRight); //添加方法的 Expression <Action> actExpression = Expression.Lambda <Action>(binary, null); actExpression.Compile()(); //()=>345+456 } { string sql = "SELECT * FROM uSER WHERE 1=1"; if (true) { sql += " and "; } if (true) { sql += " and "; } IQueryable <int> list = null; //if (true) list = list.Where(i => i > 5); //if (true) list = list.Where(i => i > 5); if (true) { Expression <Func <int, bool> > exp1 = x => x > 1; } if (true) { Expression <Func <int, bool> > exp2 = x => x > 2; } Expression <Func <int, bool> > exp3 = x => x > 1 && x > 2; //list.Where() //拼装表达式目录树,交给下端用 //Expression<Func<People, bool>> lambda = x => x.Age > 5; ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "x"); //Expression property = Expression.Property(parameterExpression, typeof(People).GetProperty("Age")); Expression property = Expression.Field(parameterExpression, typeof(People).GetField("Id")); ConstantExpression constantExpression = Expression.Constant(5, typeof(int)); BinaryExpression binary = Expression.GreaterThan(property, constantExpression);//添加方法的 Expression <Func <People, bool> > lambda = Expression.Lambda <Func <People, bool> >(binary, new ParameterExpression[] { parameterExpression }); bool bResult = lambda.Compile()(new People() { Id = 11, Name = "打兔子的猎人", Age = 28 }); } { //Expression<Func<People, bool>> lambda = x => x.Id.ToString().Equals("5"); ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "x"); Expression field = Expression.Field(parameterExpression, typeof(People).GetField("Id")); MethodCallExpression toString = Expression.Call(field, typeof(People).GetMethod("ToString"), new Expression[0]); ConstantExpression constantExpression = Expression.Constant("5", typeof(string)); MethodCallExpression equals = Expression.Call(toString, typeof(People).GetMethod("Equals"), new Expression[] { constantExpression }); Expression <Func <People, bool> > lambda = Expression.Lambda <Func <People, bool> >(equals, new ParameterExpression[] { parameterExpression }); bool bResult = lambda.Compile()(new People() { Id = 11, Name = "打兔子的猎人", Age = 28 }); } { People people = new People() { Id = 11, Name = "打兔子的猎人", Age = 28 }; PeopleCopy peopleCopy = new PeopleCopy() { Id = people.Id, Name = people.Name, Age = people.Age }; PeopleCopy peopleCopy1 = Trans <People, PeopleCopy>(people); //Expression<Func<People, PeopleCopy>> lambda = p => // new PeopleCopy() // { // Id = p.Id, // Name = p.Name, // Age = p.Age // }; //lambda.Compile()(people); ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "p"); List <MemberBinding> memberBindingList = new List <MemberBinding>(); foreach (var item in typeof(PeopleCopy).GetProperties()) { MemberExpression property = Expression.Property(parameterExpression, typeof(People).GetProperty(item.Name)); MemberBinding memberBinding = Expression.Bind(item, property); memberBindingList.Add(memberBinding); } foreach (var item in typeof(PeopleCopy).GetFields()) { MemberExpression property = Expression.Field(parameterExpression, typeof(People).GetField(item.Name)); MemberBinding memberBinding = Expression.Bind(item, property); memberBindingList.Add(memberBinding); } MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(PeopleCopy)), memberBindingList.ToArray()); Expression <Func <People, PeopleCopy> > lambda = Expression.Lambda <Func <People, PeopleCopy> >(memberInitExpression, new ParameterExpression[] { parameterExpression }); Func <People, PeopleCopy> func = lambda.Compile();//拼装是一次性的 TransExp <People, PeopleCopy>(people); TransExp <People, PeopleCopy>(people); TransExp <People, PeopleCopy>(people); TransExp <People, PeopleCopy>(people); TransExp <People, PeopleCopy>(people); TransExp <People, PeopleCopy>(people); TransExp <People, PeopleCopy>(people); TransExp <People, PeopleCopy>(new People() { Id = 12, Name = "小雨天", Age = 26 }); } #region 表达式链接 { Expression <Func <People, bool> > lambda1 = x => x.Age > 5; Expression <Func <People, bool> > lambda2 = x => x.Id > 5; Expression <Func <People, bool> > lambda3 = lambda1.And(lambda2); Expression <Func <People, bool> > lambda4 = lambda1.Or(lambda2); Expression <Func <People, bool> > lambda5 = lambda1.Not(); Do1(lambda3); Do1(lambda4); Do1(lambda5); } #endregion }