C#-迭代器

(一)迭代器是什么

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

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

(二)标准迭代器实现

// 关键接口:IEnumerator,IEnumerable                                      
// 命名空间:using System.Collections;                                    
// 可以通过同时继承IEnumerable和IEnumerator实现其中的方法                            
                                                                    
internal class CustomList : IEnumerable, IEnumerator                
{                                                                   
    private readonly int[] list;                                    
                                                                    
    // 从-1开始的光标 用于表示 数据得到了哪个位置                                       
    private int position = -1;                                      
                                                                    
    public CustomList() {                                           
        list = new[] { 1, 2, 3, 4, 5, 6, 7, 8 };                    
    }                                                               
                                                                    
    // IEnumerable                                             
                                                                    
    public IEnumerator GetEnumerator() {                            
        Reset();                                                    
        return this;                                                
    }                                                                 
                                                                    
    public object Current => list[position];                        
                                                                    
    public bool MoveNext() {                                        
        // 移动光标                                                      
        ++position;                                                 
        // 是否溢出 溢出就不合法                                               
        return position < list.Length;                              
    }                                                               
                                                                    
    // reset是重置光标位置 一般写在获取 IEnumerator对象这个函数中                        
    // 用于第一次重置光标位置                                                   
    public void Reset() {                                           
        position = -1;                                              
    }                                                               
}                 

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

(三)yield return 语法糖实现迭代器

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

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

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

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

// 关键接口:IEnumerable                                                 
// 命名空间:using System.Collections;                                   
// 让想要通过foreach遍历的自定义类实现接口中的方法GetEnumerator即可                       
                                                                   
internal class CustomList2 : IEnumerable                           
{                                                                  
    private readonly int[] list;                                   
                                                                   
    public CustomList2() {                                         
        list = new[] { 1, 2, 3, 4, 5, 6, 7, 8 };                   
    }                                                              
                                                                   
    public IEnumerator GetEnumerator() {                           
        for (int i = 0; i < list.Length; i++)                      
            // yield关键字 配合迭代器使用                                     
            // 可以理解为 暂时返回 保留当前的状态                                   
            // 一会还会在回来                                              
            // C#的语法糖                                               
            yield return list[i];                                   
    }                                                              
}                                                                  

(四)yield return 语法糖实现泛型迭代器

internal class CustomList<T> : IEnumerable                              
{                                                                       
    private readonly T[] array;                                         
                                                                        
    public CustomList(params T[] array) {                               
        this.array = array;                                             
    }                                                                   
                                                                        
    public IEnumerator GetEnumerator() {                                
        for (int i = 0; i < array.Length; i++) yield return array[i];   
    }                                                                   
}                                                                       

​ 迭代器就是可以让我们在外部直接通过 foreach 遍历对象中元素而不需要了解其结构
​ 主要的两种方式

  1. 传统方式继承两个接口,实现里面的方法
  2. 用语法糖 yield return 去返回内容,只需要继承一个接口即可

猜你喜欢

转载自blog.csdn.net/weixin_53163894/article/details/131459315