簡體   English   中英

從Expression創建樹

[英]Creating tree from Expression

如何從System.Linq.Expressions.Expression創建樹(圖)?

我希望有一個圖形(從Expression創建)與結構的節點

MyNode
{
    Expression _internalExpression = ...
    MyNode Parent {get ...} 
    IEnumerable<MyNode> Children {get ...}
}

我想過從ExpressionVisitor派生,但我不知道如何從被調用的方法(Visit,VisitBinary等)中推斷出父子關系。

更新:可能我不夠明確 - 我希望有一個代碼采用Linq(在表達式中,所以沒有花括號)並給我一個復合數據結構,其中包含我上面描述的組件(類MyNode { ......})。

所以它應該像這樣工作:

MyNode root = TreeCreator.FromExpression((x,y) => x + y);

ExpressionVisitor遍歷Expression樹並在遇到的每個節點上調用Visit方法 - 沒關系。 不幸的是,它只需要單個參數(Expression),所以我不知道它在哪個上下文(在哪個父項下)。 如果它有一個像Visit(Expression parent,Expression child)這樣的簽名,那么通過重寫Visit方法可以很容易地構建MyNode節點樹。

要容易得多遍歷了在可比你在你的問題已經描述比它試圖穿越的方式定義的圖形Expression樹。 如果你有一個IEnumerable對象代表它的子對象,就像這樣:

class MyNode
{
    MyNode Parent { get; private set; }
    IEnumerable<MyNode> Children { get; private set; }
}

然后遍歷它你只需要幾行代碼:

public static IEnumerable<T> Traverse<T>(
    this IEnumerable<T> source
    , Func<T, IEnumerable<T>> childrenSelector)
{
    var stack = new Stack<T>(source);
    while (stack.Any())
    {
        var next = stack.Pop();
        yield return next;
        foreach (var child in childrenSelector(next))
            stack.Push(child);
    }
}

我們現在可以寫:

IEnumerable<MyNode> nodes = GetNodesFromSomewhere();
var allNodesInTree = nodes.Traverse(node => node.Children);

並且這不需要嘗試假裝此節點圖表示代碼表達式時不會出現混亂。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM