I've got some code that generates various Func<>
delegates using System.Linq.Expressions
and Expression.Lambda<Func<>>.Compile()
etc. I would like to be able to serialize the generated functions into an assembly for later use. In the past I've done some stuff with System.Reflection.Emit but now that Linq Expressions I'd rather not go that route again.
Is there a mechanism to serialize a compiled expression or some sort of bridge from the Expressions
namespace to the Emit
namespace?
Edit
Some background for context: I am working on a query engine (mostly for my own edification and enjoyment). Given a SQL statement I would like to parse and transform it into a lambda function and then serialize it to disk for later (and repeated execution).
In pseudo code I am to this point:
Func<IEnumerable<T>, IEnumerable<T1>> query = Query.Parse<T, T1>("Select field AS A, field1 AS B from T where T.field2 > 5");
(where field, field1 and field2 are properties of Type T and A and B are properties of Type T1.
and I can pass any enumeration of <T>
to query
and get back and an enumeration of <T1>
which matches the query criteria.
So I would like to serialize query
to disk as an already compiled assembly so at a later date I can load it and evaluate different sets of <T>
without parsing and compiling it. I am picturing something along the lines of:
AssemblyBuilder builder = new AssemblyBuilder(...);
ModuleBuilder module = builder.DefineDynamicModule(...);
TypeBuilder type = module.DefineType(...);
type.AddMethod(query); // <--- where this piece does not exist as far as I know
builder.Emit(...)
Expression Class (System.Linq.Expressions) Provides the base class from which the classes that represent expression tree nodes are derived. It also contains static (Shared in Visual Basic) factory methods to create the various node types. This is an abstract class.
You can compile and run code represented by expression trees. This enables dynamic modification of executable code, the execution of LINQ queries in various databases, and the creation of dynamic queries. For more information about expression trees in LINQ, see How to use expression trees to build dynamic queries (C#).
Q. What LINQ expressions are used to shape results in a query? When the linq query is executed, the select clause specifies the type of values that will be produced. By using group clause you can group your results based on a key that you specify.
LambdaExpression has a CompileToMethod method that targets a MethodBuilder. Using this and Reflection.Emit you should be able to create a class and write it to an assembly.
I'm not sure what exactly your bigger picture is but looking purely at your second paragraph, you can write pure Expression based code, build it, and then open your assembly in Reflector using the "Reflection.Emit" language add-in. This piece of meta-meta trickery will show you the Reflection.Emit statements needed to generate your Expression/Lambda code dynamically.
-Oisin
I don't think that there's any way to do this. After all, an Expression
can capture arbitrary run time values, which couldn't be serialized into an assembly.
It would seem like you could get around this by calling expr.Compile().Method.GetMethodBody().GetILAsByteArray()
to get the IL as bytes, which could then be written to a MethodBuilder
in an assembly which you could then write to file. Unfortunately, this won't work - the GetMethodBody()
call fails because the delegate is dynamic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With