代码之家  ›  专栏  ›  技术社区  ›  Cheng Chen

表达式<Func<T,TResult>.Compile()的反方向?

  •  8
  • Cheng Chen  · 技术社区  · 15 年前

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

    我怎样才能:

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

    Expression Func . 有可能吗?

    4 回复  |  直到 15 年前
        1
  •  7
  •   Marc Gravell    15 年前

    没有魔法 Decompile() 为了一个 例如,除了解构IL(也许是盲肠单胞菌). 如果你想要一个表达式树,你必须 开始 有一个表达式树,所以有 Expression<Func<int, bool>> 通透。

    作为一个边缘案例,你可以 方法从委托的 .Method (the) MethodInfo .Target (the) arg0 )-但是,对于大多数涉及lambda或匿名方法的场景,这将指向capture类上的compiler generate方法,因此对您的帮助不大。它几乎仅限于以下场景:

    Func<string,int> parse = int.Parse;
    
        2
  •  5
  •   Nathan Baulch    15 年前

    将lambda传递给接受 Expression<> C编译器将在运行时向您传递一个表达式树。但是,这仅在直接传递lambda时有效,而在尝试传递从lambda创建的委托实例时无效。

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

    我找到的反编译委托实例的最接近的选项在中有详细说明 this Jean Baptiste Evain的博客文章 Mono 团队。他用最好的方法 Mono.Cecil

        3
  •  3
  •   Andrey Shchekin    14 年前


    https://github.com/ashmind/expressive

    虽然它可能不工作,因为它的结果 Compile() ,因为它是一个 DynamicMethod IManagedMethod 实施 ,不过,它应该只是工作。

    我计划实施 适配器,但还不知道什么时候。

        4
  •  1
  •   Timwi    14 年前

    你不能 反编译 电话 代表:

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