10

Since we can:

Expression<Func<int, bool>> predicate = x => x > 5;
var result = Enumerable.Range(0,10).Where(predicate.Compile());

How can I:

Func<int,bool> predicate = x => x > 5;
Expression<Func<int,bool>> exp = predicate.Decompile();

That is, I want to get the corresponding Expression of the Func. Is it possible?

Cheng Chen
  • 42,509
  • 16
  • 113
  • 174
  • 1
    No it is not possible. No expression construction is emitted to the compiler. No alchemy here. – leppie Sep 28 '10 at 05:16
  • possible duplicate of [converting a .net Func to a .net Expression>](http://stackoverflow.com/questions/767733/converting-a-net-funct-to-a-net-expressionfunct) – nawfal Aug 08 '14 at 12:07

4 Answers4

8

There is no magic Decompile() for a delegate instance, short of deconstructing the IL (perhaps with mono.cecil). If you want an expression tree, you'll have to start with an expression tree, so have Expression<Func<int, bool>> througout.

As an edge case, you can get basic method delegate information from the delegate's .Method (the MethodInfo) and .Target (the arg0) - however, for most scenarios involving a lambda or anonymous method this will point at the compiler-generate method on the capture class, so won't really help you much. It is pretty much limited to scenarios like:

Func<string,int> parse = int.Parse;
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
5

Pass the lambda to a method that accepts an Expression<> and the C# compiler will pass you an expression tree at runtime. However this only works if you pass the lambda directly, not if you try to pass a delegate instance created from a lambda.

var exp = Decompile(x => x > 5);

public Expression<Func<int, bool>> Decompile(Expression<Func<int, bool>> exp)
{
    return exp;
}

The closest option I've found for decompiling a delegate instance is detailed in this blog post from Jean-Baptiste Evain who works on the Mono team. He uses the excellent Mono.Cecil project to decompile the IL into a custom AST, then he maps it as best as possible into LINQ expressions.

Nathan Baulch
  • 20,233
  • 5
  • 52
  • 56
  • 1
    No. If you pass `x=>x>5` to `Decompile`, it will pass an `Expression`. I want to decompile a `Func`, without knowing it's content. – Cheng Chen Sep 28 '10 at 05:19
  • As Marc said, it's not possible. I just thought I'd post an example of the closest you could get to decompilation. – Nathan Baulch Sep 28 '10 at 05:35
  • 1
    Yes, I knew you were posting an example of the closest when I saw your answer. But someone else doesn't think so, and he votes down :( – Cheng Chen Sep 28 '10 at 05:47
3

You can try to use my library:
https://github.com/ashmind/expressive

Though it may not work as is for results of Compile(), since it is a DynamicMethod and getting IL of it is not straightforward. If you implement your own IManagedMethod implementation for DynamicMethod, though, it should just work.

I plan to implement DynamicMethod adapters, but do not yet know when.

Andrey Shchekin
  • 21,101
  • 19
  • 94
  • 162
1

You can’t decompile the delegate, but you can certainly create a new expression tree that simply calls the delegate:

Func<int, bool> predicate = x => x > 5;
Expression<Func<int, bool>> exp = x => predicate(x);
Timwi
  • 65,159
  • 33
  • 165
  • 230