LINQ表达树是否适合树木?

LINQ表达树是否适当的树,如图,(有针对性或没有,维基百科似乎不太一致)没有循环? 以下C#表达式中表达式树的根是什么?

(string s) => s.Length 

表达式树看起来像这样,“ – >”表示可通过其他节点访问的节点的属性名称。

  ->Parameters[0] Lambda---------Parameter(string s) \ / \->Body /->Expression \ / Member(Length) 

使用ExpressionVisitor访问LambdaExpression时,将访问ParameterExpression两次。 有没有办法使用ExpressionVisitor访问LambdaExpression,以便所有节点只访问一次,并以特定的,众所周知的顺序(预订,有序,后订单等)?

是的,是的。 LambdaExpression的实际“主干”(如果你愿意)是.Body ; 参数是关于树结构(以及它需要的)的必要元数据,但是。顶部的参数(你的虚线)实际上并不是树的function图的一部分 – 只有当这些节点在以后使用时才会使用他们感兴趣的树的实际身体,作为价值替代。

被访问的ParameterExpression两次是必不可少的,因此有人可以根据需要交换参数 – 例如,构建一个具有相同数量的参数但不同参数实例(可能更改类型)的全新LambdaExpression

订单将相当稳定,但应被视为实施细节。 例如,给定一个节点如Add(A,B) ,无论我访问A first还是B first,它都不会产生语义差异。

只是为Marc的正确答案添加一点:

LINQ表达式树是否没有循环的指向图?

首先,是的,表达式树是DAG – 有向无环图。

我们知道它们是非循环的,因为表达树是不可变的 ,因此必须从叶子构建。 在这种情况下,没有办法进行循环,因为循环中的所有节点都必须最后分配,并且显然不会发生。

因为部分是不可变的,所以表达“树”实际上不必是树本身。 正如Marc指出的那样,需要重新使用参数的参考; 这就是我们如何确定何时使用声明的参数。 重新使用其他部分虽然合法,但有些奇怪。 例如,如果要表示(int x)=>(x + 1) * (x + 1)的主体的表达式树,可以为(x + 1)创建表达式树,然后进行乘法运算两个子节点都是表达式树的节点。

使用ExpressionVisitor访问LambdaExpression时,将访问ParameterExpression两次。 有没有办法使用ExpressionVisitor访问LambdaExpression,以便所有节点只访问一次,并以特定的,众所周知的顺序(预订,有序,后订单等)?

ExpressionVisitor是一个抽象类。 您可以使用您喜欢的语义制作自己的具体版本。 例如,您可以覆盖Visit方法,使其维护已经看到的节点的HashSet,并且不会在先前已接受的节点上调用Accept。