首页 > 系统相关 >windows C#-迭代器(上)

windows C#-迭代器(上)

时间:2024-11-28 23:33:15浏览次数:7  
标签:return 迭代 windows yield C# foreach Console public

迭代器可用于逐步迭代集合,例如列表和数组。

迭代器方法或 get 访问器可对集合执行自定义迭代。 迭代器方法使用 yield return 语句返回元素,每次返回一个。 到达 yield return 语句时,会记住当前在代码中的位置。 下次调用迭代器函数时,将从该位置重新开始执行。

通过 foreach 语句或 LINQ 查询从客户端代码中使用迭代器。

在以下示例中,foreach 循环的首次迭代导致 SomeNumbers 迭代器方法继续执行,直至到达第一个 yield return 语句。 此迭代返回的值为 3,并保留当前在迭代器方法中的位置。 在循环的下次迭代中,迭代器方法的执行将从其暂停的位置继续,直至到达 yield return 语句后才会停止。 此迭代返回的值为 5,并再次保留当前在迭代器方法中的位置。 到达迭代器方法的结尾时,循环便已完成。

static void Main()
{
    foreach (int number in SomeNumbers())
    {
        Console.Write(number.ToString() + " ");
    }
    // Output: 3 5 8
    Console.ReadKey();
}

public static System.Collections.IEnumerable SomeNumbers()
{
    yield return 3;
    yield return 5;
    yield return 8;
}

迭代器方法或 get 访问器的返回类型可以是 IEnumerable、IEnumerable<T>、IEnumerator 或 IEnumerator<T>。

可以使用 yield break 语句来终止迭代。对于本主题中除简单迭代器示例以外的所有示例,请为 System.Collections 和 System.Collections.Generic 命名空间加入 using 指令。

简单的迭代器

下例包含一个位于 for 循环内的 yield return 语句。 在 Main 中,foreach 语句体的每次迭代都会创建一个对迭代器函数的调用,并将继续到下一个 yield return 语句。

static void Main()
{
    foreach (int number in EvenSequence(5, 18))
    {
        Console.Write(number.ToString() + " ");
    }
    // Output: 6 8 10 12 14 16 18
    Console.ReadKey();
}

public static System.Collections.Generic.IEnumerable<int>
    EvenSequence(int firstNumber, int lastNumber)
{
    // Yield even numbers in the range.
    for (int number = firstNumber; number <= lastNumber; number++)
    {
        if (number % 2 == 0)
        {
            yield return number;
        }
    }
}
创建集合类

在以下示例中,DaysOfTheWeek 类实现 IEnumerable 接口,此操作需要 GetEnumerator 方法。 编译器隐式调用 GetEnumerator 方法,此方法返回 IEnumerator。

GetEnumerator 方法通过使用 yield return 语句每次返回 1 个字符串。

static void Main()
{
    DaysOfTheWeek days = new DaysOfTheWeek();

    foreach (string day in days)
    {
        Console.Write(day + " ");
    }
    // Output: Sun Mon Tue Wed Thu Fri Sat
    Console.ReadKey();
}

public class DaysOfTheWeek : IEnumerable
{
    private string[] days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

    public IEnumerator GetEnumerator()
    {
        for (int index = 0; index < days.Length; index++)
        {
            // Yield each day of the week.
            yield return days[index];
        }
    }
}

下例创建了一个包含动物集合的 Zoo 类。

引用类实例 (theZoo) 的 foreach 语句隐式调用 GetEnumerator 方法。 引用 Birds 和 Mammals 属性的 foreach 语句使用 AnimalsForType 命名迭代器方法。

static void Main()
{
    Zoo theZoo = new Zoo();

    theZoo.AddMammal("Whale");
    theZoo.AddMammal("Rhinoceros");
    theZoo.AddBird("Penguin");
    theZoo.AddBird("Warbler");

    foreach (string name in theZoo)
    {
        Console.Write(name + " ");
    }
    Console.WriteLine();
    // Output: Whale Rhinoceros Penguin Warbler

    foreach (string name in theZoo.Birds)
    {
        Console.Write(name + " ");
    }
    Console.WriteLine();
    // Output: Penguin Warbler

    foreach (string name in theZoo.Mammals)
    {
        Console.Write(name + " ");
    }
    Console.WriteLine();
    // Output: Whale Rhinoceros

    Console.ReadKey();
}

public class Zoo : IEnumerable
{
    // Private members.
    private List<Animal> animals = new List<Animal>();

    // Public methods.
    public void AddMammal(string name)
    {
        animals.Add(new Animal { Name = name, Type = Animal.TypeEnum.Mammal });
    }

    public void AddBird(string name)
    {
        animals.Add(new Animal { Name = name, Type = Animal.TypeEnum.Bird });
    }

    public IEnumerator GetEnumerator()
    {
        foreach (Animal theAnimal in animals)
        {
            yield return theAnimal.Name;
        }
    }

    // Public members.
    public IEnumerable Mammals
    {
        get { return AnimalsForType(Animal.TypeEnum.Mammal); }
    }

    public IEnumerable Birds
    {
        get { return AnimalsForType(Animal.TypeEnum.Bird); }
    }

    // Private methods.
    private IEnumerable AnimalsForType(Animal.TypeEnum type)
    {
        foreach (Animal theAnimal in animals)
        {
            if (theAnimal.Type == type)
            {
                yield return theAnimal.Name;
            }
        }
    }

    // Private class.
    private class Animal
    {
        public enum TypeEnum { Bird, Mammal }

        public string Name { get; set; }
        public TypeEnum Type { get; set; }
    }
}

标签:return,迭代,windows,yield,C#,foreach,Console,public
From: https://blog.csdn.net/m0_72813396/article/details/144123085

相关文章

  • ESC字符背后的故事(27 <> 033 | x1B ?)
    ANSI不可见字符转义,正确的理解让记忆和书写变得丝滑惬意。(笔记模板由python脚本于2024年11月26日15:05:33创建,本篇笔记适合python基础扎实的coder翻阅)【学习的细节是欢悦的历程】Python官网:https://www.python.org/Free:大咖免费“圣经”教程《python完全......
  • 代码背后的哲思:C++特殊类实现的艺术与科学
    文章目录前言......
  • Day01_黑马甄选统一数仓介绍_FlinkCDC
    文章目录Day01_随堂笔记一、经典数仓架构二、传统离线大数据架构三、lambda架构Kafka是什么(可略)核心概念特性应用场景参考文档四、kappa架构五、混合架构六、传统数据入仓特点七、实时数仓现状八、湖仓一体九、统一数仓十、CDC(ChangeDataCapture:变更_数据_捕获)......
  • PyCharm常见快捷键
    文章目录PyCharm常见快捷键汇总==常用快捷键==全部快捷键1、编辑(Editing)2、查找/替换(Search/Replace)3、运行(Running)4、调试(Debugging)5、导航(Navigation)6、搜索相关(UsageSearch)7、重构(Refactoring)8、控制VCS/LocalHistory9、模版(LiveTemplates)10、基本(G......
  • 【如何提升代码工程质量】code review篇
    应该对于基本上所有软件相关的公司来说,都有committer机制,即代码写好之后会提交合并请求,待相关人员codereview通过后再进行合入,所以codereview就是代码合入代码仓库的最后一道关卡,对于代码质量的影响也是不容忽视的,那么作为在华为、阿里等大厂担任过committer的老codereviewe......
  • 12.SpringCloudAlibabaSentinel实现熔断和限流
    1.Sentinel1.1官网sentinel官网,类似SpringCloudCircuitBreaker。1.2是什么面向分布式、多语言异构化服务架构的流量治理组件。1.3下载地址https://github.com/alibaba/Sentinel/releases1.4能干吗Sentinel以流量为切入点,从流量控制、流量路由、熔断降级、系统自适......
  • MySQL 索引覆盖(Covering Index)
    MySQL索引覆盖(CoveringIndex)是一种优化查询性能的技术,指的是查询所需的所有列的数据都能够从索引中获取,不需要再回表查询数据。 1.索引覆盖的概念覆盖索引(CoveringIndex)是一种索引,它包含了SQL查询中涉及的所有列(包括查询列和条件列),不需要额外访问数据表即可完成查询......
  • jvm-44-jvm 内存性能分析工具 Eclipse Memory Analyzer Tool (MAT) / 内存分析器 (MAT
    拓展阅读JVMFULLGC生产问题I-多线程通用实现JVMFULLGC生产问题II-如何定位内存泄露?线程通用实现JVMFULLGC生产问题III-多线程执行队列的封装实现,进一步抽象jvm-44-jvm内存性能分析工具EclipseMemoryAnalyzerTool(MAT)/内存分析器(MAT)jvm-45-jvmdump......
  • 介绍一下printf,scanf
    printf函数功能概述printf是C语言中的一个标准输出函数,用于将格式化的数据输出到标准输出设备(通常是控制台)。它能够根据指定的格式字符串将变量的值转换为相应的文本格式并显示出来。格式字符串格式字符串是printf函数的关键部分,它包含普通字符和转换说明符。普通字符会......
  • React 第八节组件生命周期钩子-类式组件,函数式组件模拟生命周期用法
    概述React组件的生命周期可以分为三个主要阶段:挂载阶段(Mounting):组件被创建,插入到DOM树的过程;更新阶段(Updating):是组件中props以及state发生变化时,重新render渲染视图过程;卸载阶段(Unmounting):是DOM被从虚拟DOM树移除的过程;每个阶段都伴随着一系列的生命周期方法,这些方......