zoukankan      html  css  js  c++  java
  • 表达式树使用(二)【修改表达式树】

    Just because someone stumbles loses their way,it doesn't mean they're lost forever.Sometimes we all need a little help. 人偶尔一次失足迷失了方向不等于永远会迷失下去。有时候我们只需要有人搭把手。

    Program.cs

      class Program
        {
            static void Main(string[] args)
            {
                BaseExpression.Test();
                BaseExpressionVisitorTest.Test();
                Console.Read();
            }
        }
    

    BaseExpression.cs代码:

      /// <summary>
            /// 基本的表达式树
            /// </summary>
            public static void Test()
            {
    
                ParameterExpression a = Expression.Parameter(typeof(int), "a");
                ParameterExpression b = Expression.Parameter(typeof(int), "b");
                BinaryExpression left = Expression.Multiply(a, b);
                ConstantExpression right = Expression.Constant(2, typeof(int));
    
                BinaryExpression body = Expression.Add(left, right);
    
                LambdaExpression lambda = Expression.Lambda<Func<int, int, int>>(body, a, b);
                Console.WriteLine("lambda表达式"+lambda.ToString());
    
                //将表达式树描述的 lambda 表达式编译为可执行代码,并生成表示该 lambda 表达式的委托。
                Func<int, int, int> ttt = lambda.Compile() as Func<int, int, int>;
    
                Console.WriteLine("DynamicInvoke是结果:" + lambda.Compile().DynamicInvoke(3, 4));
    
                Console.WriteLine(ttt(3, 4));
                //--------------------------------------------------------------------------------------------
    
    
                Expression<Func<int, int, int>> newlambda = Expression.Lambda<Func<int, int, int>>(body, a, b);
                Console.WriteLine("newlambda表达式:" + newlambda.ToString());
                Console.WriteLine(newlambda.Compile()(3, 4));
    
                Func<int, int, int> mylambda = newlambda.Compile();
    
    
                //--------------------------------------------------------------------------------------------
                Expression<Func<int, int, int>> l2 = (x, y) => x + y + 3 + 4;
                Console.WriteLine("第三个表达式树示例:"+l2.ToString());
    
                Func<int, int> z1 = z => z + 3; //这是一个表达式,不是表达式树。
                Console.WriteLine("这是一个表达式示例:" + z1.ToString());
    
            }
    

    BaseExpressionVisitor.cs代码,BaseExpressionVisitorTest.cs代码

     public class BaseExpressionVisitor:ExpressionVisitor
        {
    
            //首先我们有一个类继承自ExpressionVisitor,里面有一个我们自己的Modify方法,然后我们直接调用Visit方法即可。上面我们提到了
            //Visit方法实际上是一个入口,会根据表达式的类型调用其它的Visit方法,我们要做的就是找到对应的方法重写就可以了。但是下面有一堆
            //Visit方法,我们要要覆盖哪哪些呢? 这就要看我们的表达式类型了,在我们的Where扩展方法中,我们传入的表达式树是由
            //Expression.Call方法构造的,而它返回的是MethodCallExpression所以我们第一步是覆盖VisitMethodCall。
            public Expression Modify(Expression exp)
            {
                return Visit(exp);
            }
    
            //翻译表达式树  二元运算
    
            //ExpressionVisitor类是提供给我们的表达式树解析的帮助类,我们只要定义一个类继承ExpressionVisitor,实现一个 ResolveExpression 入口方法,
            //重写VisitBinary、VisitConstant、VisitMember方法,代码如下:
            protected override Expression VisitBinary(BinaryExpression node)
            {
                if (node.NodeType == ExpressionType.Add)
                {
                    var left = this.Visit(node.Left);
                    var right = this.Visit(node.Right);                
                    return Expression.Subtract(left, right);
                }
                return base.VisitBinary(node);
            }
        }
    
        public class BaseExpressionVisitorTest
        {
            public static void Test()
            {
                Expression<Func<int, int, int>> expression = (a, b) => a + b * 2;
                Expression newExp = new BaseExpressionVisitor().Modify(expression);
    
                Console.WriteLine("修改前:");
                Console.WriteLine(expression.ToString());
                Console.WriteLine("修改后:");
                Console.WriteLine(newExp.ToString());
            }
        }
    

    项目运行结果:

    这里写图片描述

  • 相关阅读:
    JS控制台打印星星,总有你要的那一款~
    css居中方法
    line-height
    position定位
    IE盒子模型
    CSS中的盒模型
    CSS中的BEM命名
    循环语句总结(代码以C#为例)
    程序设计中的数学思维函数总结(代码以C#为例)
    转:SpringBoot 自定义异常@ContollerAdvice ExceptionHandler不起作用
  • 原文地址:https://www.cnblogs.com/Wulex/p/6962307.html
Copyright © 2011-2022 走看看