Converting Delegates to Expression Trees 9
Back when I was working at db4o, we had fun implementing a mechanism somehow similar to LINQ, to have strongly typed queries expressed using code itself. The implementation uses Mono.Cecil and Cecil.FlowAnalysis to decompile a delegate into an AST, that db4o’s query optimizer can process.
Since .net 3.5, an API, System.Linq.Expressions, can be used to get a representation of a C# lambda expression into an object graph. An expression tree. .net 4.0 will add support for statements to this API, but as far as I know, the language itself hasn’t been updated to produce those new nodes.
Anyway, a few days ago, someone on Stack Overflow, asked how to turn a delegate into a LINQ expression tree. There’s no builtin feature to do that, it’s not a straightforward process. You basically have to decompile the compiled method. I guess it’s a good thing that I’m working on a decompiler, if I need to decompile something.
Tonight I wrote a short spike to verify the feasibility of my idea, and it turns out to be pretty simple. Sample:
static void Main ()
{
Func<int, int> magic = i => i * 42;
Expression<Func<int, int>> expression =
DelegateConverter.ToExpression (magic);
Console.WriteLine (expression.ToString ());
// prints: i => i * 42
Console.WriteLine (expression.Compile ().Invoke (1));
// prints: 42
}
DelegateConverter is implemented as a simple visitor which walks over a Cecil.Decompiler AST, and generates, if possible, the according Linq Expression Tree. Pretty cool isn’t it?
You can browse the code of the spike. Keep in mind that it’s nowhere to be complete, and that it’s just a proof of concept. Still, I think it’s a pretty cool usage of the Cecil.Decompiler library.
Trackbacks
Use the following link to trackback from your own site:
http://evain.net/blog/articles/trackback/559
-
Thank you for submitting this cool story - Trackback from DotNetShoutout


Nice.
It most certainly is [Pretty cool]
Scratches head and thinks how this will end world famine, diseases and noisy neighbours in the end
Seth, let us know your findings. I mean, that would make it extra cool. Bonus point if you take into accounts the neighbour’s dog.
Cool. I just ran into just that same scenario the other night. I wanted to serialize my lambdas across the wire, but ended up to just using Expression> instead of Func as my argument. The drawback is that now i have to compile the expression when i want to use it, instead of just invoking it. So if the call doesn’t cross the wire that’s extra overhead. Haven’t done any testing to see if that’s significant or not.
Only one suggestion—make it an extension method, for extra-clean code (and chaining!) :)
I did not in a first place as you can’t constrain a generic parameter on the type Delegate.
Yes that’s Pretty cool !
Nifty.
Now if we could have full delegate to full AST (statement + expressions) this would be pure unadultered bliss. ExpressionTree are for pure expressions but I’m sure there’s something in Cecil.Decompiler that would care for both expressions and statements…
Cecil.Decompiler already provides you with a full fledged AST, here we’re just transforming it into a LINQ expression tree, because we can do it :)
We’ll even be able to extend that to the new statements nodes of the LINQ expression tree for .net 4.0.