【C#】迭代器 iterator

概念:迭代器(iterator),也称光标(cursor),是程序设计的软件设计模式,迭代器模式提供一个方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的标识。

从表现效果上看,迭代器是可以在容器对象(例如链表或数组)上遍历访问的接口,设计人员不需要关心容器对象的内存分配的实现细节。一般可以用foreach遍历的类,都是实现了迭代器的。

标准迭代器的实现方法

继承接口IEnumerator,IEnumerable

可以同时继承IEnumerator和IEnumerable实现其中的方法。

实例

class CustomList : IEnumerable, IEnumerator
{
    public int[] list;
    //光标从-1开始,表示数据到达的位置。
    public int position = -1;
    public CustomList()
    {
        list = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
    }

    #region IEnumeratable
    public IEnumerator GetEnumerator()
    {
        Reset();
        return this;
    }
    #endregion

    #region IEnumerator
    public object Current
    {
        get
        {
            return list[position];
        }
    }

    public bool MoveNext()
    {
        //移动光标
        ++position;
        //判断光标位置是否溢出,溢出就不合法。
        return position < list.Length;
    }

    //reset是重置光标位置,一般在获取IEnumerator对象这个函数中实现,
    //用于第一次重置光标位置。
    public void Reset()
    {
        position = -1;
    }
    #endregion
}

用yield return语法糖实现迭代器

yield return语法糖是C#提供的语法糖。

语法糖,也称糖衣语法,主要作用是将复杂逻辑简单化,可以增加程序的可读性,从而减少程序代码出错的机会。

接口:IEnumerable

实例

class CustomList2 : IEnumerable
{
    private int[] list;
    public CustomList2() 
    {
        list = new int[] { 1,2,3,4,5,6,7,8 };
    }
    public IEnumerator GetEnumerator()
    {
        for (int i = 0; i < list.Length; i++) 
        {
            //关键字yield,配合迭代器IEnumerator使用
            //可以理解为暂时返回,保留当前状态。
            yield return list[i];
        }
    }
}

用yield return语法糖为泛型类实现迭代器

实例

class CustomList3<T> : IEnumerable
{
    private T[] listArray;
    public CustomList3(params T[] listArray)
    {
        this.listArray = listArray;
    }
    public IEnumerator GetEnumerator()
    {
        for (int i = 0; i < listArray.Length; i++)
        {
            //关键字yield,配合迭代器IEnumerator使用
            //可以理解为暂时返回,保留当前状态。
            yield return listArray[i];
        }
    }
}

foreach本质

  1. 获取in后面对象的IEnumerator,默认调用对象中的GetEnumerator方法,不继承IEnumerator接口,只实现GetEnumerator方法,foreach也不会报错。

  2. 执行得到的IEnumerator对象中的MoveNext方法,把光标移动到下一个位置;

  3. 当MoveNext方法的返回值是true时,将对应光标的值传给Current,然后返回给item;

  4. 一次foreach循环后,执行Reset方法将光标位置归位-1,Reset方法一般在获取IEnumerator对象这个函数中实现;

  5. 当MoveNext方法的返回值是false时,终止循环。

总结

迭代器是通过foreach在外部遍历对象中元素的同时,不用了解对象内部结构。

有两种实现的方法:一种是继承IEnumerable和IEnumerator接口,并实现接口中的方法实现;另一种是继承IEnumerable接口和使用yield return语法糖返回内容。

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值