首页 文章

LINQ表达树是否适合树木?

提问于
浏览
27

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

(string s) => s.Length

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

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

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

2 回答

  • 17

    是的,是的 . LambdaExpression 的实际"trunk"(如果你愿意)是 .Body ;参数是关于树结构(以及它需要什么)的必要元数据,但是顶部的 .Parameters (你的虚线)不是功能图 - 只有当这些节点稍后在树的实际体中使用时他们很有意思,作为 Value 替代品 .

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

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

  • 17

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

    LINQ表达式树是否在没有循环的情况下定向图?

    首先,是的,表达式树是DAG - 有向无环图 .

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

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

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

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

相关问题