独上高楼网站
  •    你所在位置:首页 VS.netC#基础知识〉C#中的Iterator迭代器模式(行为型模式)
  • C#中的Iterator迭代器模式(行为型模式)
  • 作者:佚名  文章来源:中国自学编程网收集整理  发布日期:2008-10-04  浏览次数:152
  • 打印这篇文章
  • 迭代器模式我们在平时的开发中应该经常用到。不直接使用也会间接使用,我们使用foreach语句来循环就是在间接的使用迭代器模式

    迭代器就像指针一样可以向前向后移动,在.net中迭代器只能向后移动.

    动机:
    在软件的构建过程中,集合对象内部结构常常变化各异。但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素;同时这种“透明遍历”也为“同一种算法在多种集合对象上进行操作”提供了可能。使用面向对象技术将这种遍历机制抽象为“迭代器对象”为“应对变化中的集合对象”提供了一种优雅的方式。

    意图:
    提供一种方法顺序访问一个集合对象中的各个元素,而不暴露该对象的内部表示。

    ///


    /// 可迭代接口
    ///

    public interface IEnumerable
    {
    //得到迭代器
    IEnumerator GetEnumerator();
    }

    ///
    /// 迭代器接口
    ///

    public interface IEnumerator
    {
    //得到当前的对象
    object Current
    {
    get;
    }

    bool MoveNext();

    void Reset();
    }

    ///
    /// 集合类型,实现了可迭代接口
    ///

    public class MyCollection : IEnumerable
    {
    internal int[] items;

    public MyCollection()
    {
    items = new int[5] {1, 2, 3, 4, 5};
    }

    #region IEnumerable 成员

    //实现迭代接口,返回迭代器
    public IEnumerator GetEnumerator()
    {
    //在这里进行解藕,将集合对象转换为迭代器
    return new MyEnumerator(this);
    }

    #endregion
    }

    //迭代器对象,实现了迭代器接口
    internal class MyEnumerator : IEnumerator
    {

    private int nIndex;
    MyCollection collection;

    //构造函数将集合类型转换成内部成员
    public MyEnumerator(MyCollection coll)
    {
    this.collection = coll;
    nIndex = -1;
    }


    #region IEnumerator 成员

    //返回当前迭代到的对象
    public object Current
    {
    get
    {
    return collection.items[nIndex];
    }
    }

    //移动到下一个对象,指针向后移动
    public bool MoveNext()
    {
    nIndex++;

    return (nIndex < collection.items.GetLength(0));
    }

    //重设迭代器,指针回零
    public void Reset()
    {
    nIndex = -1;
    }

    #endregion
    }



    很清楚,在上面的代码中,我们通过GetEnumerator方法,将集合对象转换为了可迭代对象,这实际上是在对集合对象进行抽象,将他转换为迭代器。在这里,我们需要定义一个迭代器类,但是这是.net 1.1中的做法,在.net 2.0以后实现一个可迭代模式更加简单

    ///
    /// 集合类型,实现了可迭代接口
    ///

    public class MyCollection : IEnumerable
    {
    internal int[] items;

    public MyCollection()
    {
    items = new int[5] {1, 2, 3, 4, 5};
    }



    #region IEnumerable 成员

    public IEnumerator GetEnumerator()
    {
    for(int i = 0; i < items.Length; i++)
    {
    yield return items[i];
    }
    }

    #endregion

    #region IEnumerable 成员

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
    for(int i = 0; i < items.Length; i++)
    {
    yield return items[i];
    }
    }

    #endregion
    }


    我们通过yield return关键字来返回一个IEnumerator接口,这个关键在在编译之后会自动生成对应的迭代器的代码。

    在.net中迭代器只能先前,在c++中可以向后等其他操作。

    注意:在迭代的过程中,我们不能向集合添加内容,后移除集合里的item,这样将会导致一些问题的出现.

  • 打印这篇文章
  • 与本文主题相关的文章
  • 返回首页