快速上手Expression Tree(一):做一做装配脑袋的Expression Tree 习题

简介:

装配脑袋的习题在这里:Expression Tree上手指南 (一)

不了解Expression Tree的同学可以去看下,很好,很强大。

1: -a
2: a + b * 2
 
我把这些问题都弄成了方法,分别是Question1,Question2,….QuestionX
 

第一题:-a

 
因为实在是太短了,我不明白是什么意思,姑且认为是做取反操作吧,也就是假如输入是5,那么输出是-5.
如果让你写lambda表达式,估计没几个人写不出来吧:(a)=>{return –a;}
当然你可以简短点:(a)=>{-a}
 
OK,看一看lambda表达式可以知道有一个参数a,输出是-a。
参数是ParameterExpression.
 
所以Question1里面基本代码是:
private static void Question1()
        {
            ParameterExpression expPara = Expression.Parameter(typeof(int), "a");
        }
 
先声明一个参数a。类型是int.
接着应该对参数求反。那么我们应该使用求反表达式了。
在Msdn 里面的 里面可以查到
 
当然在Expression里面你也可以找到下面的方法:
public static UnaryExpression Negate(Expression expression);
 
于是代码可以修改为:
 
private static void Question1()
 {
      ParameterExpression expPara = Expression.Parameter(typeof(int), "a");
      UnaryExpression expNegate = Expression.Negate(expPara);
}

 

OK,剩下的就是生成lambda表达式了,

使用Expression.Lambda方法就可以生成了。lambda表达式最关键的是参数和body。

参数是(a).所以传递的是expPara.

body就是lambda表达式的主体,你可以认为是{}之间的代码,在这里传递的是expNegate.

 

为什么要生成lambda表达式??

因为可以编译lambda表达式生成委托。

 

private static void Question1()
{
    int a = 5;

    ParameterExpression expPara = Expression.Parameter(typeof(int), "a");
    UnaryExpression expNegate = Expression.Negate(expPara);
    LambdaExpression expLmd = Expression.Lambda(expNegate, expPara);
}
有了lambdaExpression后,就可以编译LambdaExpression了。
private static void Question1()
{
    int a = 5;

    ParameterExpression expPara = Expression.Parameter(typeof(int), "a");
    UnaryExpression expNegate = Expression.Negate(expPara);
    LambdaExpression expLmd = Expression.Lambda(expNegate, expPara);

    Console.WriteLine(expLmd.Compile().DynamicInvoke(a));
}

运行结果如下:
 
 
DynamicInvoke的方法签名如下:
 
//动态调用(后期绑定)由当前委托所表示的方法。
[SecuritySafeCritical]
public object DynamicInvoke(params object[] args);
 
DynamicInvoke是后期绑定,所以性能比较差。
 
 
private static void Question1()
{
    int a = 5;

    ParameterExpression expPara = Expression.Parameter(typeof(int), "a");
    UnaryExpression expNegate = Expression.Negate(expPara);
    LambdaExpression expLmd = Expression.Lambda(expNegate, expPara);

    Console.WriteLine(expLmd.Compile().DynamicInvoke(a));

    Func<int, int> funcQuestion1 = expLmd.Compile() as Func<int, int>;
    Console.WriteLine(funcQuestion1(a));
}
 

第二题:a + b * 2

 

第一步,如果你写lambda表达式,你应该怎么写??

(int a,int b)=>{return a+ b *2;}

好了,会写lambda表达式,基本上你也应该会写Expression了。

 

参数:int a,int b;

body:return a+b*2;

 

private static void Question2()
{
    ParameterExpression expA = Expression.Parameter(typeof(int), "a");
    ParameterExpression expB = Expression.Parameter(typeof(int), "b");
}

 

声明两个变量a,b类型是int.

接着要写body了。

body是a+b*2.

在这里2是常量。首先想到的是查看ExpressionType,看看有没有什么表达式代表的是常量,当然你可以找到ConstantExpression

 

于是代码变成了:

private static void Question2()
{
    ParameterExpression expA = Expression.Parameter(typeof(int), "a");
    ParameterExpression expB = Expression.Parameter(typeof(int), "b");
    ConstantExpression exp2 = Expression.Constant(2);
}
 
 

接着用()来分隔下a+b*2.

()的意思是先执行什么,后执行什么。

 

结果如下  a + (b *2)

先执行b*2,然后将b*2的结果和a相加。

 

Expression expBody = Expression.Add(expA, 
                Expression.MakeBinary(ExpressionType.Multiply, expB, exp2));
 
Expression.MakeBinary(ExpressionType.Multiply, expB, exp2))
将expB和exp2进行相乘操作。然后和expA做相加操作。生成的就是expBody了。
 
因为我们知道参数是(int,int), 结果是int
所以委托的类型是Func<int,int,int>
 
完整的代码如下:
private static void Question2()
{
    ParameterExpression expA = Expression.Parameter(typeof(int), "a");
    ParameterExpression expB = Expression.Parameter(typeof(int), "b");
    ConstantExpression exp2 = Expression.Constant(2);

    Expression expBody = Expression.Add(expA, Expression.MakeBinary(
        ExpressionType.Multiply, expB, exp2));

    Expression<Func<int, int, int>> lmd = Expression.Lambda<Func<int, int, int>>
        (expBody, expA, expB);

    Console.WriteLine(lmd.Compile()(3, 2));
}
 





本文转自LoveJenny博客园博客,原文链接:http://www.cnblogs.com/LoveJenny/archive/2011/07/19/2110137.html,如需转载请自行联系原作者
目录
相关文章
|
3月前
leetcode-1678:设计 Goal 解析器
leetcode-1678:设计 Goal 解析器
21 0
|
8月前
|
存储
Leetcode1678设计Goal解析器
请你设计一个可以解释字符串 command 的 Goal 解析器 。command 由 "G"、"()" 和/或 "(al)" 按某种顺序组成。
21 0
|
8月前
|
开发框架 .NET C#
Expression 表达树的使用
Expression 表达树的使用
46 0
【每日一题Day19】LC1678设计Goal解析器 | 简单模拟
给你字符串 command ,返回 Goal 解析器 对 command 的解释结果。
61 0
LeetCode每日一题——1678. 设计 Goal 解析器
请你设计一个可以解释字符串 command 的 Goal 解析器 。command 由 “G”、“()” 和/或 “(al)” 按某种顺序组成。
89 0
|
索引
改善代码设计 —— 简化条件表达式(Simplifying Conditional Expressions)
  系列博客       1. 改善代码设计 —— 优化函数的构成(Composing Methods)       2. 改善代码设计 —— 优化物件之间的特性(Moving Features Between Objects)       3.
902 0
零元学Expression Design 4 - Chapter 3 看小光被包围了!!如何活用「Text On Path」设计效果
原文:零元学Expression Design 4 - Chapter 3 看小光被包围了!!如何活用「Text On Path」设计效果 本章将教大家如何活用「Text On Path」,做出文绕图以及...
1017 0
零元学Expression Design 4 - Chapter 6 教你如何在5分钟内做出文字立体感效果
原文:零元学Expression Design 4 - Chapter 6 教你如何在5分钟内做出文字立体感效果 又来一篇五分钟做设计啦~ 本篇将教大家如何运用Design内建工具Blend Paths...
1006 0
|
容器
零元学Expression Blend 4 - Chapter 4元件重复运用的观念
原文:零元学Expression Blend 4 - Chapter 4元件重复运用的观念 本章将教大家Blend元件重复运用的观念,这在Silverlight设计中是非常重要的,另外加码赠送渐层工具(Gradient Tool)。
1151 0