C#自学笔记:迭代器

迭代器

  • 迭代器(iterator)有时又称光标(cursor)

  • 是程序设计的软件设计模式

  • 迭代器模式提供一个方法顺序访问一个聚合对象中的各个元素

  • 而又不暴露其内部的标识

  • 在表现效果上看

  • 是可以在容器对象(例如链表或数组)上遍历访问的接口

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

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

标准选代器的实现方法

关键接口:IEnumerator,IEnumerable

命名空间:usingSystem.Collections;

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

class CustomList : IEnumerable, IEnumerator
{
    private int[] list;

    //从-1开始的光标,用于表示数据得到了哪个位置
    private int position = -1;
    
    public CustomList()
    {
        list = new int[]{1, 2, 3, 4, 5, 6, 7, 8};
    }

    #region IEnumerable
    public IEnumerator GetIEnumerator()
    {
        Reset();
        return this;
    }
    #endregion

    public object Current 
    {
        return list[position];
    }
    
    public bool MoveNext()
    {
        //移动光标
        position++;
        //是否溢出,溢出就不合法
        return position < list.Length;
    }

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

使用

CustomList list = new CustomList();

foreach(int item in list)
{
    Console.WriteLine(item);
}

foreach本质

  1. 先获取 in 后面这个对象的 IEnumerator,会调用对象其中的 GetEnumerator() 方法 来获取
  2. 执行得到这个 IEnumerator 对象中的 MoveNext() 方法
  3. 只要 MoveNext() 方法的返回值时 true 就会去得到 Current,然后复制给 item

用 yield return 语法糖实现迭代器

yield return是C#提供给我们的语法糖

所谓语法糖,也称糖衣语法

主要作用就是将复杂逻辑简单化,可以增加程序的可读性

从而减少程序代码出错的机会

关键接口:IEnumerable

命名空间:usingSystem.Collections;

让想要通过foreach遍历的自定义类实现接口中的方法GetEnumerator即可

class CustomList : IEnumerable
{
    private int[] list;

    public CustomList()
    {
        list = new int[]{1, 2, 3, 4, 5, 6, 7, 8};
    }

    public IEnumerator GetIEnumerator()
    {
        //yield关键字 配合迭代器使用
        //可以理解为暂时返回保留当前的状态
        //一会还会在回来
        //C#的语法糖
        for (int i = 0; i < list.Length; i++)
        {
            yield return list[i];
        }
    }
}

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

class CustomList<T> : IEnumerable
{
    private T[] array;

    public CustomList(params T[] array)
    {
        this.array = array;
    }
    
    public IEnumerator GetIEnumerator()
    {
        for (int i = 0; i < array.Lenth; i++)
        {
            yield return arrray[i];
        }
    }
}

使用

CustomList<string> list = new CustomList<string>("123", "321", "333", "555");
foreach(string item in list)
{
    Console.WriteLine(item);
}
posted @ 2025-08-26 18:31  柠凉w  阅读(23)  评论(0)    收藏  举报