cyn*_*nic 27 c# linq expression-trees
LINQ表达树是否适当的树,如图,(有针对性或不指向,维基百科似乎不太一致)没有循环?以下C#表达式中表达式树的根是什么?
(string s) => s.Length
Run Code Online (Sandbox Code Playgroud)
表达式树看起来像这样," - >"表示可通过其他节点访问的节点的属性名称.
->Parameters[0]
Lambda---------Parameter(string s)
\ /
\->Body /->Expression
\ /
Member(Length)
Run Code Online (Sandbox Code Playgroud)
使用ExpressionVisitor访问LambdaExpression时,将访问ParameterExpression两次.有没有办法使用ExpressionVisitor访问LambdaExpression,以便所有节点只访问一次,并以特定的,众所周知的顺序(预订,有序,后订单等)?
Mar*_*ell 17
是的,是的.a的实际"主干"(如果你愿意)LambdaExpression是.Body; 参数是关于树结构(以及它需要的)的必要元数据,但是.Parameters在顶部(你的虚线)实际上并不是树的功能图的一部分 - 只有当这些节点在实际的后期使用时他们感兴趣的树的身体,作为价值替换.
在ParameterExpression被访问两次是必不可少的,因此,这是可能是有人掉的参数,如果他们想要的-例如,建立一个全新的LambdaExpression具有相同数量的参数,但不同的参数情况下(也许改变的类型).
订单将相当稳定,但应被视为实施细节.例如,给定一个节点Add(A,B),如果我访问A-first vs B-first ,它应该没有语义差异.
Eri*_*ert 17
只是为Marc的正确答案添加一点:
LINQ表达式树是否有没有循环的图形?
首先,是的,表达式树是DAG - 有向无环图.
我们知道它们是非循环的,因为表达树是不可变的,因此必须从叶子构建.在这种情况下,没有办法进行循环,因为循环中的所有节点都必须最后分配,并且显然不会发生.
因为部分是不可变的,所以表达"树"实际上不必是树本身.正如Marc指出的那样,您需要重新使用参数的参考; 这就是我们如何确定何时使用声明的参数.重新使用其他部分虽然合法,但有些奇怪.例如,如果要表示主体的表达式树(int x)=>(x + 1) * (x + 1),可以为其创建表达式树(x + 1),然后创建一个乘法节点,其中两个子节点都是表达式树.
使用ExpressionVisitor访问LambdaExpression时,将访问ParameterExpression两次.有没有办法使用ExpressionVisitor访问LambdaExpression,以便所有节点只访问一次,并以特定的,众所周知的顺序(预订,有序,后订单等)?
ExpressionVisitor是一个抽象类.您可以使用您喜欢的语义制作自己的具体版本.例如,您可以覆盖Visit方法,使其维护已经看到的节点的HashSet,并且不会在先前已接受的节点上调用Accept.