Fork me on GitHub

参考MSDN学习《迭代器》

 

迭代器是一种方法、get 访问器或运算符,它通过使用 yield 关键字对数组或集合类执行自定义迭代。yield 返回语句会导致源序列中的元素在访问源序列中的下一个元素之前立即返回给调用方。尽管您以方法的形式编写迭代器,但编译器会将其转换为一个实际上是状态机的嵌套类。只要客户端代码中的 foreach 循环继续进行,此类就会跟踪迭代器的位置。


 

将使用 foreach 语句从客户端代码中调用迭代器。在为类或结构创建迭代器时,您不必实现整个 IEnumerator 接口。当编译器检测到迭代器时,它将自动生成 IEnumerator 或 IEnumerator<(Of <(T>)>) 接口的 Current、MoveNext 和 Dispose 方法。


 

迭代器是可以返回相同类型的值的有序序列的一段代码

迭代器可用作方法、运算符或 get 访问器的代码体。

迭代器代码使用 yield return 语句依次返回每个元素。yield break 将终止迭代。

可以在类中实现多个迭代器。每个迭代器都必须像任何类成员一样有唯一的名称,并且可以在 foreach 语句中被客户端代码调用,如下所示:foreach(int x in SampleClass.Iterator2){}。迭代器的返回类型必须为 IEnumerable、IEnumerator、IEnumerable<(Of <(T>)>) 或 IEnumerator<(Of <(T>)>)。
迭代器是 LINQ 查询中延迟执行行为的基础。
yield 关键字用于指定返回的一个或多个值。到达 yield return 语句时,会保存当前位置。下次调用迭代器时将从此位置重新开始执行。

迭代器对集合类特别有用,它提供一种简单的方法来迭代复杂的数据结构(如二进制树)。


下面举两个自定义集合类中,迭代器的使用,可以大大减少代码的使用量。 

 

 
using System;
using System.Collections;

namespace Yield
{
    class Week : IEnumerable
    {
        string[] Days = { "星期1", "星期2", "星期3", "星期4", "星期5", "星期6", "星期7" };
        public IEnumerator GetEnumerator()
        {
            for (int i = 0; i < Days.Length; ++i)
            {
                yield return Days[i];
            }
        }
    }
    class Test
    {
        static void Main()
        {
            Week week = new Week();
            foreach (string day in week)
            {
                Console.WriteLine(day);
            }
            Console.ReadKey();
        }
    }
}

 
重新使用迭代器实现前面的自定义的Library(集合)类
using System.Collections;
using System;

namespace Library
{
    class Library : IEnumerable
    {
        ArrayList books;
        public Library()
        {
            books = new ArrayList();
        }
        public void Remove(string book)
        {
            books.Remove(book);
        }
        public void Add(string book)
        {
            books.Add(book);
        }
        public IEnumerator GetEnumerator()
        {
          // for (int i = 0; i < books.Count; i++)
          //{
          //    yield return books[i];
          // }
            foreach (string book in books)
            {
                yield return book;
            }
        }
    }
    class Test
    {
        static void Main()
        {
            Library lib = new Library();
            lib.Add("《广告》");
            lib.Add("《传播学》");
            lib.Add("《传媒研究》");
            lib.Add("《市场调研》");
            Console.WriteLine("说含有的课本包括:");
            foreach (string name in lib)
            {
                Console.WriteLine(name);
            }
            Console.ReadKey();
        }
    }
}
posted @   Halower  阅读(267)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示