Reverse of Expression>.Compile()?

后端 未结 4 1207
一个人的身影
一个人的身影 2020-12-11 17:06

Since we can:

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


        
相关标签:
4条回答
  • 2020-12-11 17:17

    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.

    0 讨论(0)
  • 2020-12-11 17:19

    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);
    
    0 讨论(0)
  • 2020-12-11 17:22

    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;
    
    0 讨论(0)
  • 2020-12-11 17:22

    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.

    0 讨论(0)
提交回复
热议问题