繁体   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