也作一下装配脑袋的Expression习题 8).(高难度)new System.Windows.Point() { X = Math.Sin(a), Y = Math.Cos(a) }

也作一下装配脑袋的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 < 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  *   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 < 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  -   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 [],  int bool >>  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(
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新手真的进步了不少

你可能感兴趣的:(也作一下装配脑袋的Expression习题 8).(高难度)new System.Windows.Point() { X = Math.Sin(a), Y = Math.Cos(a) })