简体   繁体   English

需要一种方法来获取构造给定表达式树的代码

[英]Need a method to obtain code that would construct a given expression tree

There are two ways to construct an expression tree in C#: 在C#中构造表达式树有两种方法:

  1. let the compiler rewrite a lambda and store the result; 让编译器重写lambda并存储结果;
  2. construct it piecewise, calling factory methods provided by the Expression class. 分段构造它,调用Expression类提供的工厂方法。

The first approach is simple, but it doesn't let me integrate already existing subexpressions into a resulting expression, which is my main goal. 第一种方法很简单,但它不允许我将已经存在的子表达式集成到一个结果表达式中,这是我的主要目标。 (These subs are passed to me as function parameters by design). (这些子设计作为函数参数传递给我)。

In fact, the second approach itself is the subexpression composition process, but it is very cumbersome for anything but the simplest expressions with little to no nesting involved. 实际上,第二种方法本身就是子表达式组合过程,但除了涉及很少或没有嵌套的最简单表达式之外,它对于任何事物来说都非常麻烦。

So, to get the best of two ways, while having to construct the trees piecewise, I look at copiler-generated expressions, and use them as hints. 因此,为了获得两种方法中的最佳方式,在必须分段构造树时,我会查看copiler生成的表达式,并将它们用作提示。 What I do is: write the code to construct a tree, while looking at the given tree. 我所做的是:编写代码来构建树,同时查看给定的树。 The whole process is quite a routine, so I wonder: 整个过程非常常见,所以我想知道:

  • are there tools to automate that? 有自动化的工具吗? Couldn't find any myself. 找不到自己。
  • aside from codegens, are there some other possibilities to improve my method and make it more productive? 除了代码,还有其他一些可能性来改进我的方法并提高它的效率吗?

Here's the explaination of why I need this strange process at all. 这里解释了为什么我需要这个奇怪的过程。

Expression<Func<IEnumerable<N>, IEnumerable<N>, IEnumerable<N>>>
    MyExpression = (src1, src2) => 
        src1.SelectMany(outer => lookup[outer.Value1].Select(
                inner => new N(outer, inner)));

Now, I am provided with two subexpressions, which are to be placed instead of outer.Value1 and new N(outer, inner) . 现在,我提供了两个子表达式,它们将被放置而不是outer.Value1new N(outer, inner) I can't use .Compile() and utilise them as lambdas, because I have to provide the complete expression tree for further processing intact. 我不能使用.Compile()并将它们用作lambdas,因为我必须提供完整的表达式树以便进一步处理。 I need a way to integrate them into MyExpression , and the only method I'm aware of is to construct the whole tree via Expression factories. 我需要一种方法将它们集成到MyExpression ,我唯一知道的方法是通过Expression工厂构建整个树。 But with more complex queries it gets extremely complex and error-prone. 但是对于更复杂的查询,它变得极其复杂且容易出错。

aside from codegens, are there some other possibilities to improve my method and make it more productive? 除了代码,还有其他一些可能性来改进我的方法并提高它的效率吗?

Basically you'd want to write a class that extends ExpressionVisitor that replaces some component of one expression with pieces from the other expression. 基本上你想要编写一个扩展ExpressionVisitor的类,它用一个表达式替换一个表达式的一些组件。

are there tools to automate that? 有自动化的工具吗?

LINQKit does just that. LINQKit就是这么做的 From the website's examples: 从网站的例子:

Expression<Func<Purchase,bool>> criteria1 = p => p.Price > 1000;
Expression<Func<Purchase,bool>> criteria2 = p => criteria1.Invoke (p)
                                             || p.Description.Contains ("a");

Console.WriteLine (criteria2.Expand().ToString());

Output: 输出:

p => ((p.Price > 1000) || p.Description.Contains("a")) p =>((p.Price> 1000)|| p.Description.Contains(“a”))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM