zoukankan      html  css  js  c++  java
  • Expression Tree 表达式树及练习

    首先认识表达式

    所谓的表达式就是一个有意义的式子,如:

    3   常量值的表达式
    
    num  变量表达式
    
    a+b*2
    
    -a     一元运算符的表达式
    
    Math.Sin(x) + Math.Cos(y)

    从上面的例子可以看出,构成表达式的元素有 变量、常量、运算符、函数。表达式通常有一个相应的类型,常量值表达式3的类型是int类型的。

    表达式可以组合,如a+b*2 ,可以拆分成:

    可以看出表达式的各个节点也是一个表达式,我们可以用一个树状的结构来表示每一个表达式,这个数据结构就是表达式树

    什么是表达式树

    表达式树是一种表示表达式的数据结构。System.Linq.Expression 命名空间下的Expression类和它的诸多子类就是这一数据结构的实现,每个表达式都是Expression某个子类的实例。BinaryExpression表示包含二元运算符的表达式,一个BinaryExpression由左运算数表达式、右运算数表达式、运算符。

    Expression各个子类的构造函数都是不公开的,要创建表达式树只能使用Expression类提供的静态方法。

    创建a+b*2这个表达式的表达式树

    View Code
    ParameterExpression pe1 = Expression.Parameter(typeof(int), "a");//参数a
    ParameterExpression pe2 = Expression.Parameter(typeof(int), "b");//参数b
    ConstantExpression ce = Expression.Constant(2);//常量2
    BinaryExpression be = Expression.Multiply(pe2, ce);//b*2
    BinaryExpression be1 = Expression.Add(pe1, be);//a+b*2
    LambdaExpression le1 = Expression.Lambda(be1, pe1, pe2);
    Console.WriteLine(le1.Compile().DynamicInvoke(5, 3));
    Console.WriteLine(le1.ToString());

    执行结果:

    习题

    -a

    View Code
    ParameterExpression pe = Expression.Parameter(typeof(int), "a");
     UnaryExpression ue = Expression.Negate(pe);
     LambdaExpression le = Expression.Lambda(ue, pe);
     Console.WriteLine(le.Compile().DynamicInvoke(5));
     Console.WriteLine(le.ToString());

    a + b * 2

    见上面的示例

    Math.Sin(x) + Math.Cos(y)

    View Code
    ParameterExpression pe3 = Expression.Parameter(typeof(double), "x");
    ParameterExpression pe4 = Expression.Parameter(typeof(double), "y");
    MethodCallExpression me1 = Expression.Call(null, typeof(Math).GetMethod("Sin", BindingFlags.Static | BindingFlags.Public), pe3);
    MethodCallExpression me2 = Expression.Call(null, typeof(Math).GetMethod("Cos", BindingFlags.Static | BindingFlags.Public), pe4);
    BinaryExpression be2 = Expression.Add(me1, me2);
    LambdaExpression le2 = Expression.Lambda(be2, pe3, pe4);

    new StringBuilder(“Hello”)

    View Code
    Expression body = Expression.New(typeof(StringBuilder).GetConstructor(new Type[] { typeof(string) }),
    Expression.Constant("Hello"));
    LambdaExpression le4 = Expression.Lambda(body);
    Console.WriteLine(le4.Compile());
    Console.WriteLine(le4.ToString());

    new int[] { a, b, a + b}

    View Code
     ParameterExpression pe5 = Expression.Parameter(typeof(int), "a");
    ParameterExpression pe6 = Expression.Parameter(typeof(int), "b");
    BinaryExpression be3 = Expression.Add(pe5, pe6);
    NewArrayExpression ne4 = Expression.NewArrayBounds(typeof(int[]), pe5, pe6, be3);
    LambdaExpression le3 = Expression.Lambda(ne4, pe5, pe6);
    Console.WriteLine(le3.Compile().DynamicInvoke(30, 60));
    Console.WriteLine(le3.ToString());

    a[i – 1] * i

    View Code
                ParameterExpression pe8 = Expression.Parameter(typeof(int[]), "a");
                ParameterExpression pe9 = Expression.Parameter(typeof(int), "i");
                Expression body1 = Expression.Multiply(Expression.ArrayIndex(pe8, Expression.Subtract(pe9, Expression.Constant(1))), pe9);
                LambdaExpression le5 = Expression.Lambda(body1, pe8, pe9);
                Console.WriteLine(le5.Compile().DynamicInvoke(new int[] { 1, 3, 4, 2, 3, 4 }, 2));
                Console.WriteLine(le5.ToString());
    相关资料:
  • 相关阅读:
    TextView 高亮
    Android 学习 第一章(环境搭建)
    从assets res 中读文件
    动态设置imageview 宽高
    android 算定义view 打包 jar(一次开发多次使用)
    Activity 跳转
    Android手机在开发调试时logcat不显示输出信息的解决办法
    弹出对话 AlertDialog 有按钮
    让划动 listview时 没有黑色背景
    Activity Service 数据相互操作
  • 原文地址:https://www.cnblogs.com/whx1973/p/ExpressionTree.html
Copyright © 2011-2022 走看看