Expression Trees
From The Oxygene Language Wiki
This is a Language topic
Feel free to add your notes to this topic below.
When working with Lambdas and LINQ there are two modes in which the code can be emitted. The chosen mode is dependent on the parameter type.
When the called extension methods' parameter type is a delegate type, the compiler will emit anonymous methods with the implementation for the Lambda expression.
The second mode is the use of Expression trees. When the compiler finds a lambda used on a parameter with the type System.Linq.Expressions.Expression<TDelegate>, it will treat the delegate as a defined in the TDelegate expression as a regular lambda, but instead of emitting an anonymous method it will emit calls to the Expression class, which will end up as a tree of expressions. These trees become complicated fairly quickly, as can be seen by using Reflector to decompile a program. A simple expression like:
var lData := from cust in Customers where cust.Active select cust;
Becomes a query like:
class method ConsoleApp.Main; begin var expression: ParameterExpression := Expression.Parameter(typeof(Customer), 'cust'); var expressionArray: array of ParameterExpression; var lData: IQueryable<Customer>:= Queryable.Select<Customer, Customer>( Queryable.&Where<Customer>( ConsoleApp.Customers, Expression.Lambda<Func<Customer, Boolean>>( Expression.&Property( expression, (methodof(Customer.get_Active) as MethodInfo) ), [expression] ) ), Expression.Lambda<Func<Customer, Customer>>(expression, [expression] ) ) ); end;
The tree contains the names and type info and everything else needed to be able to send such an expression over the network to a remote SQL server or to compile later on to a delegate. Since v4, both expressions and statements are supported. When compiling against 3.5, only expressions are supported.
See Also
Area: Oxygene Language
Compiler version: Oxygene 5
Language Glossary — Keywords — Types — FAQ — How To