C#-设计模式-迭代器模式

2021-06-11 12:06

阅读:352

标签:before   sse   不同   invalid   opera   initial   system.in   span   的区别   

1.定义

对于集合类对象,遍历是很重要的一种操作,但是对于不同的集合,遍历的方法都不相同,如果有办法可以将所有集合类的遍历统一起来,那将会很方便。因此便诞生了迭代器模式。

迭代器模式的实现其实很简单,大家可以把“遍历集合的方式”当做迭代器,那也就是说,就算是同一个集合对象,如果我们的遍历方式不一样,那我们的迭代器也是不同的。

而一个迭代器都应该有什么功能呢?那就是1)是否存在下一个元素;2)获取当前对象;3)坐标移动到下一个元素;4)重置坐标

(这里的坐标,代表遍历集合时标识,当坐标由第一个元素移动到最后一个元素,则遍历完成)

 

2.代码实现

2.1 我们来实现一个迭代器

public interface Iteratable
    {
        Iterator GetIterator();
    }

// 迭代器抽象类
public interface Iterator
    {
        /// 
        /// 是否可以将坐标移动至下一个
        /// 
        /// 
        bool MoveNext();

        /// 
        /// 获取当前元素
        /// 
        /// 
        Object GetCurrent();

        /// 
        /// 坐标移动至下一个元素
        /// 
        void Next();

        /// 
        /// 重置坐标
        /// 
        void Reset();
    }

/// 
/// 具体集合类
/// 
public class MyCollection : Iteratable
    {
        int[] collection;

        public MyCollection()
        {
            collection = new int[] { 1, 23, 5, 6, 3 };
        }

        public Iterator GetIterator()
        {
            return new MyIterator(this);
        }

        public int Get(int index)
        {
            return collection[index];
        }

        public int GetLength()
        {
            return collection.Length;
        }


    }

/// 
/// 具体迭代器
/// 
public class MyIterator : Iterator
    {
        private MyCollection _list = new MyCollection();
        private int _index;

        public MyIterator(MyCollection list)
        {
            _list = list;
            _index = 0;
        }

        public object GetCurrent()
        {
            return _list.Get(_index);
        }

        public bool MoveNext()
        {
            return _index  _list.GetLength();
        }

        public void Next()
        {
            if (MoveNext())
            {
                _index++;
            }
        }

        public void Reset()
        {
            _index = 0;
        }
    }

调用的时候只需要:

var collection = new MyCollection();
var iterator = collection.GetIterator();
if (iterator.MoveNext())
{
    iterator.GetCurrent();
    iterator.Next();
}

即可,大家也许觉得上面的接口似曾相识.

没错!!这里的Iteratable其实就是.Net中的IEnumerable接口,Iterator其实就是.Net中的IEnumerator接口

2.2 .Net自带的迭代器(IEnumerable和IEnumerator的区别)

  //
    // 摘要:
    //     Exposes an enumerator, which supports a simple iteration over a non-generic collection.
    public interface IEnumerable
{
    //
        // 摘要:
        //     Returns an enumerator that iterates through a collection.
        //
        // 返回结果:
        //     An System.Collections.IEnumerator object that can be used to iterate through
        //     the collection.
        IEnumerator GetEnumerator();
}

 

  //
    // 摘要:
    //     Supports a simple iteration over a non-generic collection.
    public interface IEnumerator
    {
        //
        // 摘要:
        //     Gets the element in the collection at the current position of the enumerator.
        //
        // 返回结果:
        //     The element in the collection at the current position of the enumerator.
        object Current { get; }

        //
        // 摘要:
        //     Advances the enumerator to the next element of the collection.
        //
        // 返回结果:
        //     true if the enumerator was successfully advanced to the next element; false if
        //     the enumerator has passed the end of the collection.
        //
        // 异常:
        //   T:System.InvalidOperationException:
        //     The collection was modified after the enumerator was created.
        bool MoveNext();
        //
        // 摘要:
        //     Sets the enumerator to its initial position, which is before the first element
        //     in the collection.
        //
        // 异常:
        //   T:System.InvalidOperationException:
        //     The collection was modified after the enumerator was created.
        void Reset();
    }

IEnumerable代表该即可可以被遍历,实现的方法就是返回一个迭代器。
IEnumerator是迭代器的抽象,其中的方法用来遍历一个集合。

这也是很多人比较迷惑的,两者的区别。

 

3.特点

优点:迭代器模式提供了一种统一的方法来遍历集合类,这样所有的集合类都可以使用foreach来遍历了(foreach其实就是对遍历迭代器的封装形式)

缺点:如果想在遍历的同时对集合的内容进行修改,那迭代器模式是无法胜任的。

C#-设计模式-迭代器模式

标签:before   sse   不同   invalid   opera   initial   system.in   span   的区别   

原文地址:https://www.cnblogs.com/gamov/p/10538654.html


评论


亲,登录后才可以留言!