C#中为泛型树实现IEnumerable

3

我有一个通用的树类,我想实现IEnumerable接口。我在stackoverflow上找到的之前的问题与我的问题有点不同。我知道我正在做一些错误的事情,但我不知道是什么。这是我的代码:

class Node<T>: IEnumerable<T>
{
    private T data;
    private LinkedList<Node<T>> children;

    public Node(T data)
    {
        this.data = data;
        children = new LinkedList<Node<T>>();
    }

    public void AddChildNode(Node<T> node)
    {
        children.AddFirst(node);
    }

    public void MyTraverse(Node<T> node, List<T> visited)
    {
        visited.Add(node.data);
        foreach (Node<T> kid in node.children)
            MyTraverse(kid, visited);

    }

    public IEnumerator<T> GetEnumerator()
    {
        return children.GetEnumerator();
    }


    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

在函数GetEnumerator()中,我遇到了一个转换错误,不知道该如何修复。有没有人可以帮我?

1
请发布错误信息。 - Lasse V. Karlsen
错误信息:错误 1 无法将类型'System.Collections.Generic.LinkedList<Microsoft_Example_Added.Node<T>>.Enumerator'隐式转换为类型'System.Collections.Generic.IEnumerator<T>'。D:\BoxSync\amirho\Categories\Implementation\SAT_Solvers\Z3\Microsoft_Example_Added\Microsoft_Example_Added\Node.cs 35 20 Microsoft_Example_Added - Amir Ebrahimi
在签名中添加T并不能解决问题! - Amir Ebrahimi
一件事是让方法编译通过,另一件事是让它按照你的意愿执行。你想让它做什么并返回什么? 要使其编译通过,只需执行 return children.Select(node => node.data); 但我怀疑这不会给你想要的结果。 - Lasse V. Karlsen
4个回答

2
您可能需要实现 IEnumerable<Node<T>> 接口(您正在枚举节点 Node<T>,而不是 T 实例),而不仅仅是 IEnumerable<T> 接口:
 class Node<T>: IEnumerable<Node<T>> {
   ...
    public IEnumerator<Node<T>> GetEnumerator() {
      return children.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
      return GetEnumerator();
    }
 }

2
问题在于,children是这样定义的:
private LinkedList<Node<T>> children;

这意味着childrenIEnumerable<Node<T>>,而不是IEnumerable<T>。如果您希望它成为IEnumerable<T>,则必须提取data成员。根据您的遍历方法定义方式,我还猜想您希望它递归地进入节点的子代。
public IEnumerator<T> GetEnumerator()
{
    yield return data;
    foreach (var childNode in children)
        foreach (var child in childNode)
            yield return child;
}

如果你只想返回子元素,可以使用以下代码:
public IEnumerator<T> GetEnumerator()
{
    return children.Select(node => node.data);
}

-1

获取枚举器就像是 ::

 public IEnumerator<Node<T>> GetEnumerator()
    {
        return children.GetEnumerator();
    }

-1
public class Node : IEnumerable<Node>
{
    public string Name { get; internal set; }
    public string Value { get; internal set; }

    public Node Parent { get; internal set; }
    public List<Node> Children { get; internal set; }

    public Node(string name)
    {
        if (string.IsNullOrEmpty(name))
            throw new ArgumentException($"{nameof(Name)}");

        Name = name;
        Children = new List<Node>();
    }

    IEnumerator IEnumerable.GetEnumerator()
        => GetEnumerator();

    public IEnumerator<Node> GetEnumerator()
    {
        var self = this;
        var queue = new Queue<Node>();
        queue.Enqueue(self);

        while (queue.Any())
        {
            yield return queue.Dequeue();
            foreach (var child in self.Children)
                queue.Enqueue(child);
        }
    }             
}

此外,这种方法同样有效且代码更少:

     public IEnumerator<Node> GetEnumerator()
    {
        var self = this;
        yield return self;

        foreach (var child in self.Children)
            yield return child;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接