【问题标题】:Wrapping my head around IEnumerable & IEnumerator围绕 IEnumerable 和 IEnumerator
【发布时间】:2018-08-17 03:18:17
【问题描述】:

因此,在长期中断网络管理员之后重新开始编码......并在我前进的过程中学习 C#(和 Unity)。试图绕过IEnumerable & IEnumerator

现在,这是我用来测试/弄清楚它的类的示例代码......它可以工作,递归地创建树/叶节点但是我一直在检索它们

public class NodeTest : IEnumerable
{
   public int Counter;
   public List<NodeTest> children;

   public NodeTest(int count)
   {
        Counter = count;
        Debug.Log("Creating " + count);
        NodeTest tmpNode;

     if(count>1)
     {
        children = new List<NodeTest>();
        tmpNode = new NodeTest(Counter - 1);
        children.Add(tmpNode);
        tmpNode = new NodeTest(Counter - 1);
        children.Add(tmpNode);      
     }
 }

 public IEnumerator GetEnumerator()
 {
     foreach(NodeTest n in this.children)
     {
         yield return n;
     }
 }
}

然后在我使用的其他地方:

foreach(NodeTest nt in tstNode)
{
   Debug.Log(nt.Counter);
}

哪个检索顶部节点的孩子很好,但不会遍历孩子来获取他们的孩子等。我猜我必须在 IEnumerator GetEnumerator 方法中做更多事情?

【问题讨论】:

  • 如果您的所有项目都来自 NodeTest 类型,您为什么选择使用更具体且更易于使用的接口 IEnumerable IEnumerable,这也可以让您轻松使用 LINQ 处理结果。

标签: c# ienumerable ienumerator


【解决方案1】:

您需要使NodeTest.GetEnumerator 成为递归方法。除了返回每个孩子之外,您还需要让每个孩子返回其所有孩子。 (这将使每个孩子的孩子返回其孩子等)。

public IEnumerator GetEnumerator()
{
    foreach(NodeTest n in this.children)
    {
       yield return n;
       foreach(NodeTest descendent in n)
       {
           yield return descendent;
       }
    }
}

【讨论】:

  • 打败我。请注意,这会返回父代之前的后代 - 根据业务需求,您可以将 yield return n; 移动到内部 foreach 下方。
  • 哦,天哪,我怎么没想到……谢谢安德鲁和共产国际
  • 应该指出这段代码是正确的,但是应该避免使用递归yield return,因为它们会变得非常低效。如果你递归 20 级深度,这意味着每个项目必须通过 20 级收益率返回传递回原始 foreach,然后再返回 20 级才能到达下一个项目。虽然如果你只是递归几个级别,它应该没有太大关系。
  • 是的,最多有 5-9 层深...... BSP 树。 Andrew 的代码向我抛出了一个错误,因为我在检查是否达到递归限制之前有 children = new List
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多