在C#中为自定义数据结构添加迭代器

文章目录[x]
  1. 1:代码

在使用C#内置的数据结构如 List、Stack、Queue等我们通常会使用for、while或者foreach来遍历。如果要为自定义的数据结构实现这种循环遍历功能,使用C#提供的 IEnumerable 即可。

代码


public class LinkedList<T> : IEnumerable // 实现IEnumerable接口
{
    public class Node
    {
        public T item;
        public Node next;
    }

    public Node First { get; private set; }
    public Node Last  { get; private set; }
    public int Count  { get; private set; }

    public LinkedList()
    {
        First = Last = null;
        Count = 0;
    }

    public void Add(T item)
    {
        // Do
    }

    public T RemoveAt(int index)
    {
        // Do
    }

    public bool IsEmpty()
    {
        // Do
    }

    public bool Find(T value)
    {
        // Do
    }

    public IEnumerator GetEnumerator()
    {
        return new Iterator(this);
    }

    private class Iterator : IEnumerator  // 自定义一个Iterator类,实现IEnumerator接口
    {
        private readonly LinkedList<T> list;
        private Node current;

        public object Current
        {
            get
            {
                if (!MoveNext()) throw new System.Exception("Iterator Exception");

                T item = current.item;
                current = current.next;
                return item;
            }
        }

        public Iterator(LinkedList<T> list)
        {
            this.list = list;
            current = list.First;
        }

        public bool MoveNext()
        {
            return current != null;
        }

        public void Reset()
        {
            current = list.First;
        }
    }


}

 

然后使用 foreach (var item in linkedlist) 遍历时,经历以下步骤

  • 调用GetEnumerator() 获取一个迭代器,只执行一次
  • 调用Iterator.MoveNext() 判断是否可继续迭代,如果可迭代,继续下一步,否者停止迭代
  • 调用Iterator.Current 将其返回的结果赋值给 item,然后返回上一步

这里,foreach语句只是while语句的一种简写方式。它本质上和以下while语句是等价的:

var iterator = list.GetEnumerator();
while (iterator.MoveNext())
{
    var item = iterator.Current;
    // TODO
}

 

这种通过迭代遍历并处理集合中的每个元素的方式写出的代码既清晰又简介,且不依赖于集合数据类型的具体实现,迭代器本身也是经典的设计模式之一。

 

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像