zoukankan      html  css  js  c++  java
  • 也作一下装配脑袋的Expression习题

    一.习题
    http://www.cnblogs.com/Ninputer/archive/2009/08/28/expression_tree1.html

    二.参考
    http://msdn.microsoft.com/zh-cn/library/system.linq.expressions.expression.aspx
    http://msdn.microsoft.com/zh-cn/library/bb361179%28v=VS.100%29.aspx

    三.思路
    先写出lambda,参照lambda拼出Expression

    四.做题
    (1).-a

    Expression<Func<intint>> lambdaexpression = a => -a;

    ParameterExpression p1 
    = Expression.Parameter(typeof(int), "a");
    Expression body 
    = Expression.Negate(p1);
    LambdaExpression expression 
    = Expression.Lambda(body, p1);

    Console.WriteLine(lambdaexpression.ToString());
    Console.WriteLine(expression.ToString());

    Expression.Negate方法返回类型是UnaryExpression,一元运算表达式

    (2).a + b * 2

    Expression<Func<intintint>> lambdaexpression = (a, b) => a + b * 2;

    ParameterExpression p1 
    = Expression.Parameter(typeof(int), "a");
    ParameterExpression p2 
    = Expression.Parameter(typeof(int), "b");
    Expression body 
    = Expression.Add(p1, Expression.Multiply(p2, Expression.Constant(2)));
    LambdaExpression expression 
    = Expression.Lambda(body, p1, p2);

    Console.WriteLine(lambdaexpression.ToString());
    Console.WriteLine(expression.ToString());

    Expression.Add和Expression.Multiply都返回BinaryExpression,二元运算表达式,
    Expression.Constant返回ConstantExpression,常量表达式

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

    Expression<Func<doubledoubledouble>> lambdaexpression = (x, y) => Math.Sin(x) + Math.Cos(y);

    ParameterExpression p1 
    = Expression.Parameter(typeof(double), "x");
    ParameterExpression p2 
    = Expression.Parameter(typeof(double), "y");
    Expression body 
    = Expression.Add(
        Expression.Call(
    nulltypeof(Math).GetMethod("Sin", BindingFlags.Static | BindingFlags.Public), p1)
        , Expression.Call(
    nulltypeof(Math).GetMethod("Cos", BindingFlags.Static | BindingFlags.Public), p2));
    LambdaExpression expression 
    = Expression.Lambda(body, p1, p2);

    Console.WriteLine(lambdaexpression.ToString());
    Console.WriteLine(expression.ToString());

    Expression.Call返回MethodCallExpression,方法调用表达式

    (4).new StringBuilder(“Hello”)

    Expression<Func<StringBuilder>> lambdaexpression = () => new StringBuilder("Hello");

    Expression body 
    = Expression.New(typeof(StringBuilder).GetConstructor(new Type[] { typeof(string) }),
        Expression.Constant(
    "Hello"));
    LambdaExpression expression 
    = Expression.Lambda(body);

    Console.WriteLine(lambdaexpression.ToString());
    Console.WriteLine(expression.ToString());

    Expression.New返回NewExpression,构造函数调用表达式

    (5).new int[] { a, b, a + b}

    Expression<Func<intintint[]>> lambdaexpression = (a, b) => new int[] { a, b, a + b };

    ParameterExpression p1 
    = Expression.Parameter(typeof(int), "a");
    ParameterExpression p2 
    = Expression.Parameter(typeof(int), "b");
    Expression body 
    = Expression.NewArrayInit(typeof(int), p1, p2, Expression.Add(p1, p2));
    LambdaExpression expression 
    = Expression.Lambda(body, p1, p2);

    Console.WriteLine(lambdaexpression.ToString());
    Console.WriteLine(expression.ToString());

    Expression.NewArrayInit返回NewArrayExpression,创建数组表达式

    (6).a[i – 1] * i

    Expression<Func<int[], intint>> lambdaexpression = (a, i) => a[i - 1* i;

    ParameterExpression p1 
    = Expression.Parameter(typeof(int[]), "a");
    ParameterExpression p2 
    = Expression.Parameter(typeof(int), "i");
    Expression body 
    = Expression.Multiply(Expression.ArrayIndex(p1, Expression.Subtract(p2, Expression.Constant(1))), p2);
    LambdaExpression expression 
    = Expression.Lambda(body, p1, p2);

    Console.WriteLine(lambdaexpression.ToString());
    Console.WriteLine(expression.ToString());

    Expression.ArrayIndex返回也是BinaryExpression,这个有点意外,我以为会是MethodCallExpression呢

    (7).a.Length > b | b >= 0

    Expression<Func<int[], intbool>> lambdaexpression = (a, b) => a.Length > b | b >= 0;

    ParameterExpression p1 
    = Expression.Parameter(typeof(int[]), "a");
    ParameterExpression p2 
    = Expression.Parameter(typeof(int), "b");
    Expression body 
    = Expression.Or(Expression.GreaterThan(Expression.ArrayLength(p1), p2),
        Expression.GreaterThanOrEqual(p2, Expression.Constant(
    0)));
    LambdaExpression expression 
    = Expression.Lambda(body, p1, p2);

    Console.WriteLine(lambdaexpression.ToString());
    Console.WriteLine(expression.ToString());

    Expression.GreaterThan、Expression.Or和Expression.ArrayLength都返回BinaryExpression,二元运算表达式,
    Expression.ArrayLength和(6)中一样误解了

    (8).(高难度)new System.Windows.Point() { X = Math.Sin(a), Y = Math.Cos(a) }

    Expression<Func<double, System.Windows.Point>> lambdaexpression = a => new System.Windows.Point() { X = Math.Sin(a), Y = Math.Cos(a) };

    ParameterExpression p1 
    = Expression.Parameter(typeof(double), "a");
    Expression body 
    = Expression.MemberInit(Expression.New(typeof(System.Windows.Point))
        , 
    new MemberBinding[] {
            Expression.Bind(
    typeof(System.Windows.Point).GetProperty("X"),
            Expression.Call(
    nulltypeof(Math).GetMethod("Sin", BindingFlags.Static | BindingFlags.Public), p1)),
            Expression.Bind(
    typeof(System.Windows.Point).GetProperty("Y"),
            Expression.Call(
    nulltypeof(Math).GetMethod("Cos", BindingFlags.Static | BindingFlags.Public), p1))
        });
    LambdaExpression expression 
    = Expression.Lambda(body, p1);

    Console.WriteLine(lambdaexpression.ToString());
    Console.WriteLine(expression.ToString());

    Expression.MemberInit返回MemberInitExpression,如方法名字一样是成员初始化表达式。
    果然像题目所写,难度不低,一开始以为使用Expression.New后面的参数,后来还是看了评论才会写。

    五.执行结果

    a => -a
    a => -a

    (a, b) => (a + (b * 2))
    (a, b) => (a + (b * 2))

    (x, y) => (Sin(x) + Cos(y))
    (x, y) => (Sin(x) + Cos(y))

    () => new StringBuilder("Hello")
    () => new StringBuilder("Hello")

    (a, b) => new [] {a, b, (a + b)}
    (a, b) => new [] {a, b, (a + b)}

    (a, i) => (a[(i - 1)] * i)
    (a, i) => (a[(i - 1)] * i)

    (a, b) => ((ArrayLength(a) > b) Or (b >= 0))
    (a, b) => ((ArrayLength(a) > b) Or (b >= 0))

    a => new Point() {X = Sin(a), Y = Cos(a)}
    a => new Point() {X = Sin(a), Y = Cos(a)}
    Press any key to continue . . .

    作完这些习题,感觉让我这个Expression新手真的进步了不少
  • 相关阅读:
    LINUX_bash
    【c++】必须在类初始化列表中初始化的几种情况
    Hadoop 学习笔记 (八) hadoop2.2.0 测试环境部署 及两种启动方式
    hadoop各版本下载
    mapreduce (六) MapReduce实现去重 NullWritable的使用
    hadoop 生态系统版本对应问题
    mapreduce (五) MapReduce实现倒排索引 修改版 combiner是把同一个机器上的多个map的结果先聚合一次
    mapreduce (四) MapReduce实现Grep+sort
    ctr预估模型
    mapreduce (七) 几个实例
  • 原文地址:https://www.cnblogs.com/llcto/p/2136334.html
Copyright © 2011-2022 走看看