首先认识表达式
所谓的表达式就是一个有意义的式子,如:
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());
相关资料: