Express 表达式目录树详解

        其实就是二叉树数据结构. .

      把lambda 表达式以运算符和连接符为节点 ,一层层的拆开而已。

//1.形如Expression<Func<TSource, bool>> 表达式目录树--Linq To Sql--表达式目录树
//2.和委托的区别:在外面包裹一层 Expression<>,二者可以转换吗? 可以通过Compile() 转换成一个委托
//3.Expression不能带有大括号,只能有一行代码//

          Expression<Func<int, int, int>> exp = (m, n) => m * n + 2; 

4.本质;展示表达式目录树--是一个类的封装,描述了这个结构:身体部分;参数部分;,身体部分内部:左边和右边; 左边:m*n   右边:2

   var erpPlu = exp.Compile();//表达式目录树可以通过compile 转换成一个委托

动态拼装Expression

        ////表达式目录树的拼装---最基础版本

复制代码
 Expression<Func<int>> expression = () => 123 + 234; //没有参数,返回int
                ConstantExpression expression1 = Expression.Constant(123); //常量表达式
                ConstantExpression expression2 = Expression.Constant(234); //常量表达式 
                BinaryExpression binaryExpression = Expression.Add(expression1, expression2); //二元表达式
                Expression<Func<int>> expressionReslut = Expression.Lambda<Func<int>>(binaryExpression);      //转lambda
                Func<int> func = expressionReslut.Compile();   //转委托
                int iResult = func.Invoke();    //执行委托
复制代码

   //表达式目录树的拼装---带参数版本

复制代码
 Expression<Func<int, int>> expression1 = m => m + 1;
                ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "m");//参数表达式
                ConstantExpression constant = Expression.Constant(1, typeof(int));//常量表达式
                BinaryExpression addExpression = Expression.Add(parameterExpression, constant);//+
                Expression<Func<int, int>> expression = Expression.Lambda<Func<int, int>>(addExpression, new ParameterExpression[1]
                {
                      parameterExpression
                });//转lambda
                Func<int, int> func1 = expression.Compile();
                int iResult1 = func1.Invoke(5);
复制代码

 

 //表达式目录树的拼装---带有多个参数的

复制代码
 Expression<Func<int, int, int>> expression = (m, n) => m * n + 2;
                ParameterExpression parameterExpressionM = Expression.Parameter(typeof(int), "m");//参数表达式
                ParameterExpression parameterExpressionN = Expression.Parameter(typeof(int), "n");//参数表达式
                BinaryExpression multiply = Expression.Multiply(parameterExpressionM, parameterExpressionN);//*
                ConstantExpression constantExpression = Expression.Constant(2);//常量表达式
                BinaryExpression plus = Expression.Add(multiply, constantExpression);//+
                Expression<Func<int, int, int>> expression1 = Expression.Lambda<Func<int, int, int>>(plus, new ParameterExpression[2]
                {
                      parameterExpressionM,
                      parameterExpressionN
                });//转lambda
                Func<int, int, int> func1 = expression1.Compile();
                int iResult1 = func1.Invoke(10, 20);
复制代码

 //表达式目录树的拼装---高级篇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Expression<Func<People, bool>> predicate = c => c.Id == 10;
//1.声明一个变量C;
                       ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "c");
                       //2.c.id,调用c.的属性---people的属性id,先获取属性                          
                       FieldInfo fieldId = typeof(People).GetField("Id"); //id 获取属性--反射
                       MemberExpression idExp = Expression.Field(parameterExpression, fieldId);//通过parameterExpression来获取 调用Id
                       //3.==  Equeals 是个方法 ,是id的方法,id 是int类型,应该获取int 的 ===
                       ConstantExpression constant10 = Expression.Constant(10, typeof(int));
                       //c.id==10;
                       Expression expressionExp = Expression.Equal(idExp, constant10);
                       Expression<Func<People, bool>> predicate1 = Expression.Lambda<Func<People, bool>>(expressionExp, new ParameterExpression[1]
                       {
                               parameterExpression
                       });
                       Func<People, bool> func1 = predicate1.Compile();
                       bool bResult1 = func1.Invoke(new People()
                       {
                           Id = 10
                       });

  表达式目录树的拼装---超级篇     建议从右往左拼装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
Expression<Func<People, bool>> predicate = c =>
                     c.Id.ToString() == "10"
                     && c.Name.Equals("Seven")
                     && c.Age > 35;
 
                       //1.拼装c.Age > 35;
                       ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "c");
                       ConstantExpression constant35 = Expression.Constant(35);
                       //age
                       PropertyInfo propAge = typeof(People).GetProperty("Age");
                       //c.Age
                       var ageExp = Expression.Property(parameterExpression, propAge);
                       //c.Age > 35
                       var cagExp = Expression.GreaterThan(ageExp, constant35);
                       Console.WriteLine("****************************************************");
                       //拼装:c.Name.Equals("Seven")
                       //字符串Seven
                       ConstantExpression constantSeven = Expression.Constant("Seven");
                       // Name属性
                       PropertyInfo propName = typeof(People).GetProperty("Name");
                       //c.Name
                       var nameExp = Expression.Property(parameterExpression, propName);
                       //获取equals方法
                       MethodInfo equals = typeof(string).GetMethod("Equals", new Type[] { typeof(string) });
                       //c.Name.Equals("Seven")
                       var NameExp = Expression.Call(nameExp, equals, constantSeven);
                       Console.WriteLine("****************************************************");
                       //拼装:c.Id.ToString() == "10"
                       ConstantExpression constantExpression10 = Expression.Constant("10", typeof(string));
                       //id
                       FieldInfo fieldId = typeof(People).GetField("Id");
                       //c.Id
                       var idExp = Expression.Field(parameterExpression, fieldId);
                       //获取ToString
                       MethodInfo toString = typeof(int).GetMethod("ToString", new Type[0]);
                       //c.Id.ToString();  Expression.Call:调用方法
                       var toStringExp = Expression.Call(idExp, toString, Array.Empty<Expression>());
                       // c.Id.ToString()=="10"
                       var EqualExp = Expression.Equal(toStringExp, constantExpression10);
                       Console.WriteLine("****************************************************");
                       //c.Id.ToString() == "10"&&c.Name.Equals("Seven")
                       var plus = Expression.AndAlso(EqualExp, NameExp);
                       //c.Id.ToString() == "10"&&c.Name.Equals("Seven") && c.Age > 35
                       var exp = Expression.AndAlso(plus, cagExp);
                       Expression<Func<People, bool>> predicate1 = Expression.Lambda<Func<People, bool>>(exp, new ParameterExpression[1]
                       {
                            parameterExpression
                       });
                       Func<People, bool> func1 = predicate1.Compile();
                       bool bResult1 = func1.Invoke(new People()
                       {
                           Id = 10,
                           Name = "Seven",
                           Age = 36
                       });

  

posted @   wolfsocket  阅读(213)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示