为通用树c#实现IEnumerable

时间:2016-04-13 08:54:18

标签: c# generics ienumerable

我有一个通用的树类,我想为它实现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()中,我得到一个我不知道如何修复的转换错误。任何人都可以帮助我吗?

4 个答案:

答案 0 :(得分: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();
    }
 }

答案 1 :(得分: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);
}

答案 2 :(得分:-1)

获取枚举器就像::

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

答案 3 :(得分:-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;
    }