二十三、迭代器

访问官网 迭代器概念迭代器编程指南

1、迭代器是什么

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

从表面上看:

迭代器是可以在容器对象(例如链表、数组等)上遍历的接口。

设计人员无需关心容器对象的内存分配的实现细节。

可以用 foreach 遍历的类,都是实现了迭代器的。

2、标准迭代器的实现方法

  • 关键接口:IEnumerableIEnumerator
    • namespace:using System.Collections;
    • 可以通过同时继承两个接口实现其中的方法
  • Demo:
using System.Collections;

// demo类
class MyList : IEnumerable, IEnumerator
{
    private int[] list;
    private int position = -1; // 游标

    // IEnumerator 的 Current
    public object Current 
    {
        get { return list[position]; }
    }

    public MyList() { 
        list = new int[]{ 1, 5, 20, 9, 2, 77 };
    }

    // 实现 IEnumerable 的方法
    public IEnumerator GetEnumerator()
    {
        Reset();
        return this;
    }

    // 实现 IEnumerator 的 MoveNext 方法
    public bool MoveNext()
    {
        ++position;
        return  position < list.Length;
    }

    // 实现 IEnumerator 的 Reset 方法
    public void Reset()
    {
        position = -1;
    }
}

// 测试代码
MyList myList = new MyList();
/**
 * foreach本质:
 *  1、调用 in 后面对象的 GetEnumerator 方法获取 IEnumerator
 *      小注:其实继不继承 IEnumerable 不重要,主要是要有能获取 IEnumerator 的 GetEnumerator 方法
 *  2、执行对象实现的 IEnumerator 接口的 MoveNext 方法
 *  3、只要 MoveNext 返回 true,就会得到 IEnumerator 的 Current 并赋值给 item
 *      小注:返回 false 就结束循环
 */
foreach (var item in myList)
{
	Console.WriteLine(item); // 完美遍历!~
}

3、用 yield return 语法糖实现迭代器

  • yield return 是C#提供的语法糖
  • 关键接口:IEnumerable
  • namespace:using System.Collections;
  • 实现接口中的 GetEnumerator 方法即可
class MyNewList : IEnumerable
{
    private int[] list;

    public MyNewList()
    {
        list = new int[] { 6, 22, 7, 13, 32, 99, 0 };
    }
    
    // 只需要实现 GetEnumerator 方法即可
    public IEnumerator GetEnumerator()
    {
        for (int i = 0; i < list.Length; i++) 
        {
            /** 语法糖~
             * yield 关键字 配合迭代器使用
             * 可以理解为 暂时返回,保留当前状态
             */
            yield return list[i];
        }
    }
}

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

没啥好讲的,直接上代码

class MyNewTList<T> : IEnumerable
{
    private T[] list;

    public MyNewTList(params T[] list) 
    { 
        this.list = list;
    }

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

// 测试代码
MyNewTList<string> myNewTList = new MyNewTList<string>("aaa", "bbb", "ccc");
foreach (var item in myNewTList)
{
    Console.WriteLine(item); // 完美遍历!~
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纯纯的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值