一.习题

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<int, int>> 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<int, int, int>> lambdaexpression = (a, b) => a + b * ;

ParameterExpression p1 = Expression.Parameter(typeof(int), "a");
ParameterExpression p2 = Expression.Parameter(typeof(int), "b");
Expression body = Expression.Add(p1, Expression.Multiply(p2, Expression.Constant()));
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<double, double, double>> 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(null, typeof(Math).GetMethod("Sin", BindingFlags.Static | BindingFlags.Public), p1)
    , Expression.Call(null, typeof(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<int, int, int[]>> 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[], int, int>> lambdaexpression = (a, i) => a[i - ] * 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())), 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[], int, bool>> lambdaexpression = (a, b) => a.Length > b | b >= ;

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()));
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(null, typeof(Math).GetMethod("Sin", BindingFlags.Static | BindingFlags.Public), p1)),
        Expression.Bind(typeof(System.Windows.Point).GetProperty("Y"),
        Expression.Call(null, typeof(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新手真的进步了不少

转载自:http://www.cnblogs.com/llcto/archive/2011/08/12/2136334.html

谢谢浏览!

也作一下装配脑袋的Expression习题【转】的更多相关文章

  1. 学习ExpressionTree(做装配脑袋出的练习题)

    1 // 第一题:画出下列表达式的表达式树.一开始,您很可能不知道某些操作其实也是表达式(比如取数组的运算符a[2]),不过没有关系,后面的习题将帮你验证这一点. //-a ParameterExpr ...

  2. 使用Expression Tree构建动态LINQ查询

    这篇文章介绍一个有意思的话题,也是经常被人问到的:如何构建动态LINQ查询?所谓动态,主要的意思在于查询的条件可以随机组合,动态添加,而不是固定的写法.这个在很多系统开发过程中是非常有用的. 我这里给 ...

  3. 开源纯C#工控网关+组态软件(八)表达式编译器

    一.   引子 监控画面的主要功能之一就是跟踪下位机变量变化,并将这些变化展现为动画.大部分时候,界面上一个图元组件的某个状态,与单一变量Tag绑定,比如电机的运行态,绑定一个MotorRunning ...

  4. 关于GC和析构函数的一个趣题

    这个有趣的问题感谢装配脑袋友情提供. 请看如下代码: public class Dummy { public static Dummy Instance; ; ~Dummy() { Instance ...

  5. Atitit 表达式原理 语法分析 原理与实践 解析java的dsl  递归下降是现阶段主流的语法分析方法

    Atitit 表达式原理 语法分析 原理与实践 解析java的dsl  递归下降是现阶段主流的语法分析方法 于是我们可以把上面的语法改写成如下形式:1 合并前缀1 语法分析有自上而下和自下而上两种分析 ...

  6. 性能优化-列表类型转换(ConvertList<TSource, TResult>)

    之前,在项目中看到过一段通用列表类型转换的代码,直接的实现便是用反射.大概看了下,它用在领域模型转DTO和SOA接口中契约实体的转换等等.首先,它使用了反射,其次,还是在循环中使用,便有了优化的想法. ...

  7. T-SQL: 17 个与日期时间相关的自定义函数(UDF),周日作为周的最后一天,均不受 @@DateFirst、语言版本影响!

    原文:T-SQL: 17 个与日期时间相关的自定义函数(UDF),周日作为周的最后一天,均不受 @@DateFirst.语言版本影响! CSDN 的 Blog 太滥了!无时不刻地在坏! 开始抢救性搬家 ...

  8. 列表类型转换(ConvertList<TSource, TResult>)

    性能优化-列表类型转换(ConvertList<TSource, TResult>) 2013-12-16 16:55 by stevey, 426 阅读, 7 评论, 收藏, 编辑 之前 ...

  9. .NET的前世今生与将来

    笔者注 谨以此文纪念我敬重的2016年9月17日去世的 装配脑袋 逝世两周年 让大家久等了,前后花了1年的时间,几经改版,终于完成撰写了一万字长文,回顾和展望.NET这16年来的成功与失败.最终能成文 ...

随机推荐

  1. Docker第二弹之常用命令

    Docker的常用命令 底层原理 Docker是如何工作的 Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上, 然后通过Socket连接从客户端访问,守护进程从 ...

  2. Java匹马行天下之学编程的起点——编程常识知多少

    学编程的起点——编程常识知多少 前言: 刚去大学那会,我就知道我被录取的学院是软件学院,还知道一点就是软件学院主要是学电脑的,但具体要学什么其实一无所知.待的时间久了,慢慢的,像“编程”.“软件”.“ ...

  3. Android studio移动项目到另外一个文件夹,结果不能安装的解决方法

    删除.gradle , .idea , build 三个文件夹即可

  4. 最全的.NET Core跨平台微服务学习资源

    一.Asp.net Core基础 微软中文官网:https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/ 微软英文官网:https:/ ...

  5. java基础(10):继承、抽象类

    1. 继承 1.1 继承的概念 在现实生活中,继承一般指的是子女继承父辈的财产.在程序中,继承描述的是事物之间的所属关系,通过继承可以使多种事物之间形成一种关系体系.例如公司中的研发部员工和维护部员工 ...

  6. 为什么要做外链建设?seo优化与发布外链速度有哪些联系?

    对于SEO员工来说,我们每天都在处理网页.从内容创建的角度来看,我们每天创建大量的URL并进入索引状态.与网站的受欢迎程度相比,网站每天也会生成大量的外部链接. 实际上,相对于链接而言,它满足了搜索引 ...

  7. android studio 菜单中的app运行按钮上有个叉号,原因与解决办法(自己去百度)

    http://blog.csdn.net/sz0268/article/details/51706397 : 在Android studio写代码中,直接建立项目,写代码然后运行是不会一般是不会出现这 ...

  8. mysql - 锁及事务的认识

    mysql事务特性:一致性原子性隔离性持久性 //mysql 事务隔离级别 读未提交 读未提交的数据 读已提交 读已提交的数据 串行序列化 一个事务完成了再执行另一个事务 可重复读(数据库默认) 就算 ...

  9. AQS(抽象队列同步器)

    AQS(全称为AbstractQueuedSynchronizer),即抽象队列同步器,它维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列. state的访问方 ...

  10. PHP fread 文件系统函数

    定义和用法 fread - 读取文件(可安全用于二进制文件) 版本支持 PHP4 PHP5 PHP7 支持 支持 支持 语法 fread ( resource $handle , int $lengt ...