【问题标题】:how do I create GetEnumerator of my circular list?如何创建循环列表的 GetEnumerator?
【发布时间】:2015-05-26 04:20:16
【问题描述】:

我必须创建自己的循环列表,我使用的是通用列表。

首先我创建Node<D> 类,它代表数据和元素的下一个

      private class Node<D> {
            public D info;
            public Node<D> next;

            public Node() {

            }

            public Node(D p) {
                info = p;
            }
        } 

为了创建循环列表,我创建了circularList&lt;T&gt; 类。此类使用Node&lt;&gt; 作为元素的项。

这是CircularList&lt;T&gt;

class CircularList<T> : IEnumerable<T> {
    public Node<T> start;
    public Node<T> rear;
    public int count = 0;
    public CircularList(T firstItem) {
        start = new Node<T>(firstItem);
        rear = start;
        rear.next = start;
    }

    public void Insert(T newItem) {
        //Inserting code here
    }

    public void Update(T oldItem, T newItem) {
        //Updating code is here
    }

    public void Delete(T theItem) {
        //deleting code is here
    }


}

当我开始使用foreach循环时

foreach(string item in CircularList<string>){

}

我收到一条错误消息,指出 circularlist 类需要 GetEnumerator()

实际上我可以循环我所有的循环列表,但我使用的是do-while,我需要Node&lt;T&gt; 来启动循环。但我不想使用Nodedo-while

如何创建 GetEnumerator()?

任何帮助表示赞赏。 :)

谢谢

注意:我真的-真的不明白IEnumerable和那些东西,请通过示例和解释来轻松。

【问题讨论】:

  • 你是否从IEnumerable接口实现了GetEnumerator()? foreach 需要GetEnumerator()。如果您尚未实施,您应该会收到 compile 时间错误。
  • 是的,但我不知道该返回什么。

标签: c# foreach enumerator circular-list


【解决方案1】:

您需要从IEnumerable 实现GetEnumerator() 方法才能使foreach 工作。

使用如下内容:

public class CircularList<T> : IEnumerable<T>
{
    private List<T> mylist = new List<T>();

    public T this[int index]
    {
        get
        {
            return this.mylist[index];
        }
        set
        {
            this.mylist.Insert(index, value);
        }
    }

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

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

mylist 维护T 类型的列表,您可以使用insertupdatedelete

编辑

myList 只是您的“自定义”列表的后备存储。只要您正确实现了底层功能,myList 就可以是数组、数组列表等。 为简单起见,我在这里使用了List&lt;T&gt;,它已经实现了接口IEnumerable&lt;T&gt;IEnumerator&lt;T&gt;(注意IEnumera**tor** 不是IEnumerable)。

有关IEnumeratorIEnumerable之间区别的更多详细信息,请参阅this答案

此外,foreach 语句隐藏了枚举数的复杂性。 详情请见IEnumerator

编译器会将foreach 变成这样的:

CircularList<string> testList=new CircularList<string>();

IEnumerator testEnumerator= testList.GetEnumerator();
while (testEnumerator.MoveNext())
{
  string yourForEachIteratorVariable = (string)testEnumerator.Current
   ...
}

请注意,此处的代码仅用于说明目的。您可以/应该根据您的需要/要求进行修改以使其更加灵活和“高性能”。

对于链表,您不需要支持List&lt;T&gt;,您可以简单地在head 节点上添加/插入并实现GetEnumerator(),如下所示:

 public IEnumerator<T> GetEnumerator()
  {
   var node = start;
   while(node != null)
   {
    yield return node.info;
    node = node.next;
 }
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
 return GetEnumerator();
}

【讨论】:

  • 谢谢,现在我明白了....我没有看到最后一个 mylist 维护了您将插入、更新和删除的类型 T 的列表。。 +1 + 接受
  • 使用后备列表确实违背了向消费者展示链接列表的目的。
  • @Enigmativity,请看我编辑的答案,支持列表类型仅用于“简单”的说明。
  • @ANewGuyInTown - 暗示这是 OP 的正确方法有点误导。这通常是正确的方法,但不适用于链表。
猜你喜欢
  • 2022-07-12
  • 2019-02-02
  • 2022-01-11
  • 2019-06-19
  • 1970-01-01
  • 1970-01-01
  • 2015-06-09
  • 2020-07-13
  • 1970-01-01
相关资源
最近更新 更多