C#之Expression表达式目录树
2022-03-14 23:50
2061 查看
一、Expression是什么
1、和委托的区别
a、委托是编译时,表达式目录树是运行时,在应用程序运行过程中可以重新赋值
b、委托相当于是拿到别人dll文件,只能调用里面的方法;表达式目录树相当于拿到了别人的源码,可以进行扩展
2、Expression本质
a、表达式目录树是一个类的封装,描述了一个结构,有身体部分和参数部分
b、表达式目录树展开后的每一个节点也是一个表达式目录树
二、Expression动态拼接
1、最基础版本
Expression<Func<int>> expression = () => 123 + 456; ConstantExpression constant1= Expression.Constant(123,typeof(int)); ConstantExpression constant2 = Expression.Constant(456, typeof(int)); BinaryExpression binaryExpression =Expression.Add(constant1, constant2); Expression<Func<int>> expressionReslut = Expression.Lambda<Func<int>>(binaryExpression,Array.Empty<ParameterExpression>()); Func<int> func = expressionReslut.Compile(); var result = func.Invoke();
2、带参数版本
Expression<Func<int,int>> expression = m => m + 123; ParameterExpression parameterExpression =Expression.Parameter(typeof(int),"m"); ConstantExpression constantExpression = Expression.Constant(123, typeof(int)); BinaryExpression binaryExpression =Expression.Add(parameterExpression, constantExpression); Expression<Func<int,int>> expressionReslut = Expression.Lambda<Func<int,int>>(binaryExpression, new ParameterExpression[1] parameterExpression }); Func<int,int> func = expressionReslut.Compile(); var result = func.Invoke(10);
3、带有多个参数
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 }); Func<int, int, int> func1 = expression1.Compile(); int iResult1 = func1.Invoke(20, 30);
4、对象字段值比较
如果碰到很长的表达式目录树,建议先拼装右边,再拼装左边
Expression<Func<User, bool>> expression = (x) => x.Id.ToString() == "1" && x.Name.Equals("xiaohemiao"); // 1、声明参数 ParameterExpression parameterExpression=Expression.Parameter(typeof(User),"x"); // 2、因为要拼装x.Name,所以要先找到Name PropertyInfo propName = typeof(User).GetProperty("Name"); // 3、拼装x.Name MemberExpression memberExpression = Expression.Property(parameterExpression, propName); // 4、因为需要调用Equals,所以要先获取Equals方法 MethodInfo methodInfo= typeof(string).GetMethod("Equals",new Type[] { typeof(string)}); // 5、调用Equals方法,x.Name.Equals("xiaohemiao") ,调用需要“xiaohemiao”,所以先声明一个字符串常量 ConstantExpression constantExpressionRight =Expression.Constant("xiaohemiao", typeof(string)); // 6、拼装x.Name.Equals("xiaohemiao") MethodCallExpression MethodCallExpressionRight=Expression.Call(memberExpression, methodInfo, constantExpressionRight); // 7、开始拼装左边 拼装x.Id,所以先找到Id PropertyInfo propId = typeof(User).GetProperty("Id"); // 8、拼装x.Id MemberExpression memberExpressionId = Expression.Property(parameterExpression, propId); // 9、因为要拼装x.Id.ToString(),所以先找到ToString方法 MethodInfo toString = typeof(int).GetMethod("ToString", new Type[0] { }); // 10、开始拼装x.Id.ToString() MethodCallExpression methodCallExpressionLeft1=Expression.Call(memberExpressionId, toString, Array.Empty<Expression>()); // 11、需要声明一个常量 ConstantExpression constantExpressionLeft= Expression.Constant("1",typeof(string)); // 12、拼装x.Id.ToString().Equals("1"),需要调用Equals方法,先获取Equals方法--上面已经获取过,可以直接使用 BinaryExpression BinaryExpression = Expression.Equal(methodCallExpressionLeft1, constantExpressionLeft); // 13、左边和右边都拼装好了,现在要把左边和右边 && 起来 BinaryExpression binaryExpression=Expression.AndAlso(BinaryExpression, MethodCallExpressionRight); Expression<Func<User, bool>> expression1 = Expression.Lambda<Func<User, bool>>(binaryExpression, new ParameterExpression[1] { parameterExpression }); Func<User, bool> func = expression1.Compile(); var result = func.Invoke(new User() { Id=1, Name="xiaohemiao" });
相关文章推荐
- C#简单实现表达式目录树(Expression)
- 05.表达式目录树Expression
- c#中巧用Expression表达式 解决类似于sql中 select in 的查询
- delegate、Lambda表达式、Func委托和Expression(TDelegate)表达式目录树
- Expression表达式目录树
- delegate、Lambda表达式、Func委托和Expression(TDelegate)表达式目录树
- C#通过正规表达式获取文件根目录、路径、文件名、后缀名
- C# 表达式目录树的应用详解
- Lambda表达式 c# 经验谈:巧用Expression表达式 解决类似于sql中 select in 的查询(适合于中小型项目)
- C# Expression表达式笔记
- 第十五节:Expression表达式目录树(与委托的区别、自行拼接、总结几类实例间的拷贝)
- C#学习基本概念之表达式树(二)--ParamterExpression
- c# 经验谈:巧用Expression表达式 解决类似于sql中 select in 的查询(适合于中小型项目)
- delegate、Lambda表达式、Func委托和Expression(TDelegate)表达式目录树
- Expression表达式目录树(十二)
- c# 经验谈:巧用Expression表达式 解决类似于sql中 select in 的查询
- c# 经验谈:巧用Expression表达式 解决类似于sql中 select in 的查询
- C#正则表达式编程(二):Regex类用法
- C# 中Linq的学习(查询表达式基础知识)示例
- [转帖]C#如何使用正则表达式来校验字段串输入的系列函数