【问题标题】:Implementing IEnumerable for generic tree c#为通用树 c# 实现 IEnumerable
【发布时间】:2016-04-13 08:54:17
【问题描述】:

我有一个通用树类,我想为其实现 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 ​​无法将类型 'System.Collections.Generic.LinkedList>.Enumerator' 隐式转换为 'System.Collections.Generic.IEnumerator' D :\BoxSync\amirho\Categories\Implementation\SAT_Solvers\Z3\Microsoft_Example_Added\Microsoft_Example_Added\Node.cs 35 20 Microsoft_Example_Added
  • 在签名中加T并不能解决问题!
  • 一件事是让方法编译,另一件事是让它做你想做的事。 您希望它做什么并返回? 要使其编译,只需执行 return children.Select(node =&gt; node.data); 但我怀疑这会给您想要的。

标签: c# generics ienumerable


【解决方案1】:

您可能想要IEnumerable&lt;Node&lt;T&gt;&gt; 接口实现(您正在枚举节点 Node&lt;T&gt;,而不是T 实例),而不仅仅是IEnumerable&lt;T&gt; 一个:

 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&lt;Node&lt;T&gt;&gt;,而不是IEnumerable&lt;T&gt;

    由于您希望它为IEnumerable&lt;T&gt;,因此您必须提取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);
    }
    

    【讨论】:

      【解决方案3】:

      获取枚举器就像 ::

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

      【讨论】:

        【解决方案4】:
        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;
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-12-28
          • 1970-01-01
          • 1970-01-01
          • 2014-12-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多