打造自己的LINQ Provider(上):Expression Tree揭秘
摘要:在.NET Framework 3.5中提供了LINQ 支持后,LINQ就以其强大而优雅的编程方式赢得了开发人员的喜爱,而各种LINQ Provider更是满天飞,如LINQ to NHibernate、LINQ to Google等,大有“一切皆LINQ”的趋势。LINQ本身也提供了很好的扩展性,使得我们可以轻松的编写属于自己的LINQ Provider。
[1] 认识表达式目录树1[2] 认识表达式目录树2
[3] 表达式目录树与委托
[4] 执行表达式目录树
[5] 访问与修改表达式目录树
[6] 为什么需要表达式目录树和总结
执行表达式目录树
前面已经可以构造出一个表达式目录树了,现在看看如何去执行表达式目录树。我们需要调用Compile方法来创建一个可执行委托,并且调用该委托,如下面的代码:
static void Main(string[] args) { ParameterExpression paraLeft = Expression.Parameter(typeof(int), "a"); ParameterExpression paraRight = Expression.Parameter(typeof(int), "b"); BinaryExpression binaryLeft = Expression.Multiply(paraLeft, paraRight); ConstantExpression conRight = Expression.Constant(2, typeof(int)); BinaryExpression binaryBody = Expression.Add(binaryLeft, conRight); Expression<Func<int, int, int>> lambda = Expression.Lambda<Func<int, int, int>>(binaryBody, paraLeft, paraRight); Func<int, int, int> myLambda = lambda.Compile(); int result = myLambda(2, 3); Console.WriteLine("result:" + result.ToString()); Console.Read(); }
运行后输出的结果:
这里我们只要简单的调用Compile方法就可以了,事实上在.NET Framework中是调用了一个名为ExpressionCompiler的内部类来做表达式目录树的执行(注意此处的Compiler不等同于编译器的编译)。另外,只能执行表示Lambda表达式的表达式目录树,即LambdaExpression或者Expression<TDelegate>类型。如果表达式目录树不是表示Lambda表达式,需要调用Lambda方法创建一个新的表达式。如下面的代码:
static void Main(string[] args) { BinaryExpression body = Expression.Add( Expression.Constant(2), Expression.Constant(3)); Expression<Func<int>> expression = Expression.Lambda<Func<int>>(body, null); Func<int> lambda = expression.Compile(); Console.WriteLine(lambda()); }