views:

332

answers:

2

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(...)
+3  A: 

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

x0n
I think I see what you are getting at but if you look at my edit: I do not know what the Expressions will look like until runtime evaluation of the input.
dkackman
+2  A: 

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.

kvb