C# LINQ表达式树是正确的树吗?

C# LINQ表达式树是正确的树吗?,c#,linq,expression-trees,C#,Linq,Expression Trees,LINQ表达式树是否是正确的树,例如,没有循环的图(有向图或无向图,维基百科似乎不太同意)?以下C#表达式的表达式树的根是什么 (string s) => s.Length 表达式树如下所示,其中“->”表示可通过另一个节点访问的节点的属性的名称 ->Parameters[0] Lambda---------Parameter(string s) \ / \->Body /->Expression

LINQ表达式树是否是正确的树,例如,没有循环的图(有向图或无向图,维基百科似乎不太同意)?以下C#表达式的表达式树的根是什么

(string s) => s.Length
表达式树如下所示,其中“->”表示可通过另一个节点访问的节点的属性的名称

     ->Parameters[0]
 Lambda---------Parameter(string s)
    \               /
     \->Body       /->Expression
      \           /
      Member(Length)
使用ExpressionVisitor访问LambdaExpression时,将访问ParameterExpression两次。有没有一种方法可以使用ExpressionVisitor来访问LambdaExpression,以便以特定的、众所周知的顺序(预订单、顺序、后订单等)访问所有节点一次?

某种程度上,是的。
LambdaExpression
的实际“主干”(如果愿意)是
.Body
;这些参数是关于树的结构(以及它需要什么)的必要元数据,但是顶部(虚线)的
.parameters
并不是树的功能图的一部分-只有当这些节点稍后在树的实际主体中使用时,它们才是有趣的,作为值替换

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


订单将相当稳定,但应视为实施细节。例如,给定一个节点,如
Add(a,B)
,我是否访问
a
-first与
B
-first,在语义上应该没有区别。

只需为Marc的正确答案添加一点内容:

LINQ表达式树是没有圈的有向图吗

首先,是的,表达式树是一个DAG——一个有向无环图

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

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

使用ExpressionVisitor访问LambdaExpression时,将访问ParameterExpression两次。是否有一种方法可以使用ExpressionVisitor访问LambdaExpression,以便以特定的、众所周知的顺序(预订单、顺序、后订单等)访问所有节点一次


ExpressionVisitor是一个抽象类。您可以制作自己的具体版本,具有您喜欢的语义。例如,您可以覆盖Visit方法,使其维护已看到的节点的哈希集,而不对其先前已接受的节点调用Accept。

为什么需要它,为什么关心它?@DanielHilgarth我认为这是一个关于表达式树的基本概念如何工作的合理问题。这是一个问答网站,提问者似乎很好奇表达式树是如何工作的。这个问题可能是为了投票,但很有趣。有人知道数学表达式树的分支是什么吗?我想看一看数学书concepts@DavidHoerster当前位置这确实是一个合理的问题,但人们经常会问这样的问题,试图解决一些问题。我宁愿知道原来的问题,并帮助解决它。谢谢。最好知道表达式类的哪些属性构成表达式树中的“适当”边。@愤世嫉俗地说,几乎所有的
表达式
都不是
LambdaExpression.Parameters
!虽然我只考虑3.5风格的表达方式,但我想不出还有其他的表达方式;在一些4.0节点类型上可能还有其他一些类似的元数据值……感谢@ericlippert,这使它更加清晰。还有一个问题:在第二个(非嵌套的)lambda中重用相同的参数实例,甚至在第二个lambdas参数集合中使用它,可以吗?lambda1:(x)=>x.Y lambda2:(x)=>x.Z在source.Where(lambda1).OrderBy(lambda2)中使用,这是C#LINQ不会产生的。但是它被认为是一个有效的表达树吗?@Tom67:这是一个问答网站。发布那个问题!谢谢@ericlippert,现在我希望得到最终答案。