日期:2014-05-18 浏览次数:20844 次
表达式树的设计是基于"code as data"的思想,它把代码表示成树状的数据结构,树状结构中的每个节点都是一个表达式(这个表达式是一个广义的概念,并不是编程语言中所指的表达式语法),因此称为表达式树。
表达式树的本质在于将代码组织在数据段,而不是代码段,这对于运行时更改代码是非常重要的。
System.Linq.Expressions命名空间下含有很多类来表示不同的表达式,这些类都继承自抽象的Expression基类,Expression含有丰富的静态方法用于创建各种各样的表达式类。
一、编程方式构建表达式树
下面的代码以编程的方式构建表达式树
Expression firstArg = Expression.Constant(2); Expression secondArg = Expression.Constant(3); Expression add = Expression.Add(firstArg, secondArg); Console.WriteLine(add);
二、表达式树与代理(编译表达式树成为代理)
将表达式树转化为代理的关键点在于Expression<TDelegate>类,继承关系如图:
可以使用Expression.Lambda方法创建Expression<TDelegate>对象,Expression<TDelegate>对象包含Compile方法,用于将表达式编译成可执行代码并生成表示其lambda表达式的代理对象,
下面的代码表示转换过程:
Expression firstArg = Expression.Constant(2); Expression secondArg = Expression.Constant(3); Expression add = Expression.Add(firstArg, secondArg); Func<int> compiled = Expression.Lambda<Func<int>>(add).Compile(); Console.WriteLine(compiled());
可以通过lambda表达式构造Expression<TDelegate>对象:
Expression<Func<string, string, bool>> expression = (x, y) => x.StartsWith(y); var compiled = expression.Compile(); Console.WriteLine(compiled("First", "Second")); Console.WriteLine(compiled("First", "Fir"));
MethodInfo method = typeof(string).GetMethod ("StartsWith", new[] { typeof(string) }); var target = Expression.Parameter(typeof(string), "x"); var methodArg = Expression.Parameter(typeof(string), "y"); Expression[] methodArgs = new[] { methodArg }; Expression call = Expression.Call(target, method, methodArgs); var lambdaParameters = new[] { target, methodArg }; var lambda = Expression.Lambda<Func<string, string, bool>> (call, lambdaParameters); var compiled = lambda.Compile(); Console.WriteLine(compiled("First", "Second")); Console.WriteLine(compiled("First", "Fir"));