迭代器模式(IteratorPattern)

文章目录

1.迭代器模式定义

能在不暴露集合(列表、栈、树等)底层表现形式的情况下遍历集合所有元素

er)

2.UML类图

  1. 迭代器 (Iterator): 接口声明了遍历集合所需的操作: 获取下一个元素、 获取当前位置和重新开始迭代等。
  2. 具体迭代器 (Concrete Iterators): 实现遍历集合的一种特定算法。 迭代器对象必须跟踪自身遍历的进度。 这使得多个迭代器可以相互独立地遍历同一集合。
  3. 集合 (Collection): 接口声明一个或多个方法来获取与集合兼容的迭代器。 请注意, 返回方法的类型必须被声明为迭代器接口, 因此具体集合可以返回各种不同种类的迭代器。
  4. 具体集合 (Concrete Collections): 会在客户端请求迭代器时返回一个特定的具体迭代器类实体

3.C# 中的迭代器

  1. 集合要实现IEnuerable接口,实现GetEnumerator方法,这个成员方法会返回一个IEnumerator对象,这个对象就是我们的迭代器;
  2. 迭代器实现IEnumerator接口,这个接口只有三个方法:MoveNext方法用于判断是否已经到达了迭代的终点,Current属性用于获取当前迭代的值,Reset方法用于重置迭代器。
  3. 此外,这两个类分别还有对应的泛型类。IEnumerator为了实现对特定对象的释放,又额外继承了IDisposable接口。

4.代码实现

我这里的迭代器类和集合类使用了C#自带的IEnumerator和IEnumerable借口
具体迭代器:

csharp 复制代码
public class MyRangeIterator : IEnumerator<int>
{
    int end;
    int cur;
    
    public MyRangeIterator(MyRange parent)
    {
        this.end = parent.end;
        this.cur = parent.start;
    }
    
    public int Current => cur;

    object IEnumerator.Current => Current;

    public void Dispose() { }

    public bool MoveNext()
    {
        Console.WriteLine("MyRangeIterator MoveNext : " + cur);
        return ++cur <= end;
    }

    public void Reset() { }
}

具体集合:

csharp 复制代码
public class MyRange : IEnumerable<int>
{
    private int start, end;
    
    public MyRange(int start, int end)
    {
        this.start = start;
        this.end = end;
    }
    
    public IEnumerator<int> GetEnumerator()
    {
        return new MyRangeIterator(this);//待实现
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

使用:

csharp 复制代码
var range = new MyRange(1,5);
Console.WriteLine("new range");
range.Foreach(i =>
{
    Console.WriteLine("print : " + i);
});

new range

MyRangeIterator MoveNext : 1

print : 2

MyRangeIterator MoveNext : 2

print : 3

MyRangeIterator MoveNext : 3

print : 4

MyRangeIterator MoveNext : 4

print : 5

MyRangeIterator MoveNext : 5

5.使用yield简化迭代器代码

csharp 复制代码
class MyRange : IEnumerable<int>
{
    private int start, end;
    public MyRange(int start, int end)
    {
        this.start = start;
        this.end = end;
    }
    public IEnumerator<int> GetEnumerator()
    {
        for (int i = start+1; i <= end; i++)//注意这里,直接使用一个循环替代了前面的迭代器
        {
            yield return i;
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
  • yield关键字用于返回值为IEnumerable、IEnumerator、IEnumerable、IEnumerator函数中,它有两个使用方法,yield break和yield return。
  • 返回值为IEnumerable、IEnumerator、IEnumerable、IEnumerator的函数会自动生成一个迭代器,每个yield语句都表示一次暂停或中断。
  • yield break用于中断当前迭代,此时,自动生成的迭代器的MoveNext()会返回false。
  • yield return用于暂停当前函数,并返回一个值,返回的值可以在迭代器中的Current属性中获取。
  • 再次调用迭代器的MoveNext时,会自动从上一个yield return之后开始运行。

仅使用一个迭代函数:

csharp 复制代码
 IEnumerable<int> MyRange(int start,int end)
 {
     for (int i = start+1; i <= end; i++)
     {
         yield return i;
     }
 }

测试:

csharp 复制代码
var range = MyRange(1,5);
Console.WriteLine("new range");
range.Foreach(i =>
{
    Console.WriteLine("print : " + i);
});

new range

MyRangeIterator MoveNext : 1

print : 2

MyRangeIterator MoveNext : 2

print : 3

MyRangeIterator MoveNext : 3

print : 4

MyRangeIterator MoveNext : 4

print : 5

MyRangeIterator MoveNext : 5

相关推荐
workflower13 小时前
情境感知系统
人工智能·机器学习·设计模式·自然语言处理·机器人
咖啡八杯14 小时前
设计模式中的原则
设计模式·接口隔离原则·里氏替换原则·开闭原则·合成复用原则·单一职责原则
安冬的码畜日常16 小时前
【工欲善其事】深入理解 Node.js 带并发上限的异步任务批量执行逻辑
javascript·设计模式·node.js·ai编程·异步编程·并发执行
AI大法师1 天前
一个机场如何被做成 IP 场景:宝可梦机场的设计方法总结
大数据·人工智能·设计模式·新媒体运营
晚安code1 天前
干掉成山的 if-else:工厂造、策略选,一文讲透两个模式的配合
后端·设计模式
workflower2 天前
从幻觉,到现实
人工智能·深度学习·机器学习·设计模式·机器人
电子科技圈2 天前
第二代无线平台历久弥新,赋能物联网创新迭代
人工智能·嵌入式硬件·mcu·物联网·设计模式·硬件架构·iot
choumin2 天前
创建型模式——工厂方法模式
c++·设计模式·工厂方法模式·创建型模式
choumin2 天前
创建型模式——原型模式
c++·设计模式·原型模式·创建型模式
37.2℃9952 天前
Claude Design哪个公司技术好
python·设计模式