C#基础学习--枚举器和迭代器

news2024/10/2 22:19:52

目录

枚举器和可枚举类型

 IEnumerator 接口

IEnumerable 接口

实现 IEnumerable 和 IEnumerator的示例

 泛型枚举接口

迭代器

迭代器块

使用迭代器来创建枚举器

使用迭代器来创建可枚举类型

常见迭代器模式

产生多个可枚举类型

 将迭代器作为属性

迭代器实质


枚举器和可枚举类型

数组按需提供一个叫做枚举器的对象。枚举器可以依次返回请求数组中的元素。

调用对象的GetEnumerator 方法可以获取一个对象枚举器,可以知道枚举器的类型。实现GetEnumerator方法的类型叫做 可枚举类型。数组是可枚举数组

foreach 结构设计用来和可枚举类型一起使用。只要它遍历的对象是可枚举类型,就可以执行如下操作:

 IEnumerator 接口

实现了 IEnumerator 接口的枚举器包含3个函数成员:Current ,MoveNext, Reset

枚举器与序列中的当前项保持联系的方式完全取决于实现,可以通过对象引用,索引值或其他方式来实现

IEnumerable 接口

可枚举类型是指实现了 IEnumerable 接口的类。IEnumerable 接口只有一个成员---GetEnumerator方法,它返回对象的枚举器

实现 IEnumerable 和 IEnumerator的示例

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace Csharpzuoye
{
    
    class ColorEnumerator : IEnumerator
    {
        string[] _colors;
        int _position = -1;

        public ColorEnumerator(string[] theColors)  //构造函数
        {
            _colors = new string[theColors.Length];
            for (int i = 0; i < theColors.Length; i++)
                _colors[i] = theColors[i];
        }

        public object Current  //实现Current
        {
            get
            {
                if (_position == -1)
                    throw new InvalidOperationException();
                if (_position >= _colors.Length)
                    throw new InvalidOperationException();

                return _colors[_position];
            }
        }

        public bool MoveNext()  //实现MoveNext
        {
            if(_position < _colors.Length - 1)
            {
                _position++;
                return true;
            }
            else
            {
                return false;
            }
        }

        public void Reset()
        {
            _position = -1;
        }
    }

    class Spectrum : IEnumerable
    {
        string[] Colors = { "violet", "blue", "cyan", "green", "yellow", "orange", "red" };

        public IEnumerator GetEnumerator()
        {
            return new ColorEnumerator(Colors);
        }
    }

    class Program
    {
        static void Main()
        {
            Spectrum spectrum = new Spectrum();
            foreach (string color in spectrum)
                Console.WriteLine(color);
        }
    }
}

 泛型枚举接口

IEnumerable<T> 和 IEnumerator<T> 泛型

  泛型与非泛型的差别:

非泛型接口的实现不是类型安全的,它们返回object 类型的引用,然后必须转化为实际类型。

而泛型接口的枚举器是类型安全的,它返回实际类型的引用。如果创建自己的可枚举类,应该实现这些泛型接口

迭代器

我们可以把手动编码的可枚举类型和枚举器替换为有迭代器生成的可枚举类型和枚举器

迭代器块

迭代器块是有一个或多个 yield' 语句的代码块。下面三种任意一种都可以是迭代器块

迭代器块与其他代码块不同。其他块包含的语句被当作是命令式的,需要先执行代码块的第一个语句,然后执行后面的语句,最后离开块。

迭代器块不是需要在同一时间执行的一串命令式命令,而是描述了希望编译器为我们创建的枚举器类的行为。

编译器得到有关如何枚举项的描述后,使用它来构建包含所有需要的方法和属性实现的枚举器类。结果类被嵌套包含在迭代器声明的类中

使用迭代器来创建枚举器

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace Csharpzuoye
{
    
    class MyClass
    {
        public IEnumerator<string> GetEnumerator()
        {
            return BlackAndWhite();  //返回枚举器
        }

              //返回枚举器
        public IEnumerator<string> BlackAndWhite()  //迭代器
        {
            yield return "black";
            yield return "gray";
            yield return "white";
        }
    }

    class Program
    {
        static void Main()
        {
            MyClass mc = new MyClass();

            foreach (string shade in mc)  //使用MyClass的实例
                Console.WriteLine(shade);
        }
    }
}

使用迭代器来创建可枚举类型

在本节中我们使用迭代器来创建可枚举类型,而不是枚举器

图中左边的迭代器代码演示了它的返回类型是IEnumerable<string> 

图中右边演示了他有一个嵌套类实现了IEnumerator<string> 和 IEnumerator<string>

常见迭代器模式

产生多个可枚举类型

 将迭代器作为属性

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace Csharpzuoye
{
    
    class Spectrum
    {
        bool _listFromUVtoIR;

        string[] colors = { "violet", "blue", "cyan", "green", "yellow", "orange", "red" };

        public Spectrum(bool listFromUVtoIR)
        {
            _listFromUVtoIR = listFromUVtoIR;
        }

        public IEnumerator<string> GetEnumerator()
        {
            return _listFromUVtoIR ? UVtoIR : IRtoUV;
        }

        public IEnumerator<string> UVtoIR
        {
            get
            {
                for (int i = 0; i < colors.Length; i++)
                    yield return colors[i];
            }
        }

        public IEnumerator<string> IRtoUV
        {
            get
            {
                for (int i = colors.Length - 1; i >= 0; i--)
                    yield return colors[i];
            }
        }
    }

    class Program
    {
        static void Main()
        {
            Spectrum startUV = new Spectrum(true);
            Spectrum startIR = new Spectrum(false);

            foreach (string color in startUV)
                Console.Write("{0} ", color);
            Console.WriteLine();
            foreach (string color in startIR)
                Console.Write("{0} ", color);
            Console.WriteLine();
        }
    }
}

迭代器实质

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/436761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【分享】比ChatGPT还厉害?可以自主解决复杂任务的Auto-GPT迅速走红(内含体验地址)

哈喽&#xff0c;大家好&#xff0c;我是木易巷~ 最近木易巷在了解Auto GPT&#xff0c;今天给大家分享一下~ 自主解决复杂任务的Auto-GPT 什么是Auto-GPT&#xff1f; Auto-GPT 是一款开源 Python 应用程序&#xff0c;由开发者用户 Significant Gravitas 于 2023 年 3 月 30…

钉钉接入“通义千问”大模型,输入斜杠“/”唤起智能服务

4月18日&#xff0c;钉钉总裁叶军在2023春季钉峰会上宣布&#xff0c;钉钉正式接入阿里巴巴“通义千问”大模型&#xff0c;输入“&#xff0f;”在钉钉即可唤起 10 余项 AI 能力&#xff0c;叶军现场演示了群聊、文档、视频会议及应用开发四个场景。 现场展示中&#xff0c;只…

C++:智能指针(auto_ptr/unique_ptr/shared_ptr/weak_ptr)

为什么需要智能指针&#xff1f; C没有垃圾回收机制。 #include<iostream> using namespace std;int div() {int a, b;cin >> a >> b;if (b 0)throw invalid_argument("除0错误");return a / b; }void Func() {// 1、如果p1这里new 抛异常会如何…

网络原理数据链路层

嘿嘿,又见面了,今天为大家带来数据链路层的相关知识.这个层面的知识离咱们程序员太遥远了,我们简单介绍一下就行 1.以太网 2.认识Mac地址 3.区分Mac地址和IP地址 4.MTU 5.DNS 1.以太网 以太网是数据链路层和物理层的使用的网络,物理层用的不咋多,我们就先不讲了,直接看数…

论文阅读 - Segment Anything

文章目录 0 前言1 预备知识1.1 深度学习训练框架1.2 语义分割训练框架 2 SAM的任务3 SAM的模型3.1 模型整体结构3.2 Image encoder3.3 Prompt encoder3.4 Mask decoder3.5 训练细节 4 SAM的数据4.1 模型辅助的手动标注阶段4.2 半自动阶段4.3 全自动阶段 5 SAM的应用5.1 拿来主义…

什么是感知机——图文并茂,由浅入深

什么是感知机——图文并茂&#xff0c;由浅入深 文章目录 什么是感知机——图文并茂&#xff0c;由浅入深引言感知机的引入宝宝版青年版老夫聊发少年狂版激活函数 感知机的应用与门或门 感知机与深度学习感知机与神经网络感知机和深度学习什么关系呢&#xff1f; 引言 生活中常…

【4月比赛合集】19场可报名的「创新应用」和「程序设计」大奖赛,任君挑选!

CompHub 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号同时会推送最新的比赛消息&#xff0c;欢迎关注&#xff01; 更多比赛信息见 CompHub主页 或 点击文末阅读原文 以下信息仅供参考&#xff0c;以比赛官网为准 目录 创新应用赛&…

【SpringBoot】一:SpringBoot的基础(上)

文章目录 1. 脚手架创建项目1.1使用Spring Initializr1.2 IDEA中使用脚手架创建项目 2. 代码结构2.1 单一结构2.2 多模块2.3 包和主类2.4 pom文件2.4.1 父项目2.4.2 启动器2.4.3 不使用父项目 3. 运行SpringBoot项目 1. 脚手架创建项目 脚手架辅助创建程序的工具&#xff0c;S…

《Java8实战》第12章 新的日期和时间 API

原来的Java的时间类Date、java.util.Calendar类都不太好&#xff0c;以语言无关方式格式化和解析日期或时间的 DateFormat 方法也有线程安全的问题 12.1 LocalDate、LocalTime、LocalDateTime、Instant、Duration 以及 Period 12.1.1 使用 LocalDate 和 LocalTime LocalDate…

Maven的概述

Maven是干什么用的 maven提供了一套标准的项目结构&#xff0c;这样可以让不同编译器所写的代码在任何一个编译器上都可以运行。 maven提供了一套标准化的构建流程 编译&#xff0c;测试&#xff0c;打包&#xff0c;发布->maven提供了简单的命令可以完成这些操作&#xf…

1秒解决notion客户端所有问题-历史上最简单

1 前言 你是否安装了enhancer后&#xff0c;notion打不开&#xff0c;一直报错&#xff1f;你是否为实现notion客户端汉化和大纲的各种操作而各种苦恼&#xff1f;你是否不习惯使用网页的开始&#xff0c;很想有一个客户端的notion&#xff01; 全部解决&#xff01; 2 网页…

如何理解线程池

线程池的核心状态 核心状态说明 在线程池的核心类ThreadPoolExecutor中&#xff0c;定义了几个线程池在运行过程中的核心状态&#xff0c;源码如下&#xff1a; private static final int COUNT_BITS Integer.SIZE - 3;private static final int CAPACITY (1 << CO…

不良事件报告系统源码,PHP医院安全(不良)事件报告系统源码,在大型医院稳定运行多年

PHP医院安全&#xff08;不良&#xff09;事件报告系统源码&#xff0c;不良事件系统源码&#xff0c;有演示&#xff0c;在大型医院稳定运行多年。 系统技术说明 技术架构&#xff1a;前后端分离&#xff0c;仓储模式 开发语言&#xff1a;PHP 开发工具&#xff1a;VSco…

AE开发20210531之色彩设置、渐变色、符号颜色、属性框内数据操作、另存图层、设计添加属性对话框

笔记 选择ID变化后&#xff0c;清空symbol&#xff0c;添加进新的来&#xff0c;渐变色设置符号颜色对属性框中数据进行操作另存图层&#xff0c;save方法savelayer打开属性对话框自己设计添加属性对话框 课程设计下一节课&#xff0c;图层的渲染 点符号&#xff0c;线符号&…

satoken+ gateway网关统一鉴权 初版

一&#xff1a;感谢大佬 本博客内容 参考了satoken官网实现&#xff0c;satoken官网地址&#xff1a; https://sa-token.cc/doc.html#/micro/gateway-auth 二&#xff1a;项目层级介绍 jinyi-gateway 网关服务jinyi-user-service 用户服务 2.1 jinyi-user-api 2.2 jinyi-use…

Docker 快速上手

目录 一、初始Docker 二、Docker基本操作 1、镜像操作命令 2、容器相关命令 3、数据卷 三、Deckerfile自定义镜像 1、镜像结构 2、自定义镜像 四、DockerCompose 一、初始Docker 镜像(lmage):Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起&am…

Docker中配置Mysql主从复制

新建主服务器容器实例3307 进入/mydata/mysql-master/conf目录下新建my.cnf vim my.cnf [mysqld] ## 设置server_id&#xff0c;同一局域网中需要唯一 server_id101 ## 指定不需要同步的数据库名称 binlog-ignore-dbmysql ## 开启二进制日志功能 log-binmall-mysql-bin …

Spring中读取和存储Bean对象(5000字详解)

在Spring项目的创建和使用(Spring项目的创建和使用_蜡笔小心眼子&#xff01;的博客-CSDN博客)中&#xff0c;我们详细讲解了如何通过配置XML文件存取Bean对象&#xff0c;但是没新增一个Bean对象时就需要添加一个Bean标签&#xff0c;而且如果同一个Bean对象被多次注册到Sprin…

轻松掌握K8S命名空间、Pod、Deployment部署工具

1、NameSpace命名空间 在官方可视化工具界面为如下 也可以使用kubectl命令行具体看使用命令行操作 2、Pod应用组 k8s所说的应用通常就是指pod&#xff0c;一个pod可以部署多个容器。容器间共享网络空间&#xff0c;共享存储 3、根据应用类型选择部署Pod的工具 k8s官方也有对…

运行Omniverse Replicator Headlessly

运行Replicator Headlessly 学习目标 本教程的目的是向您展示如何不费吹灰之力地使用 Replicator。 Headless 在这种情况下意味着计算设备没有显示器或外围设备&#xff0c;例如键盘和鼠标。 为了做到这一点&#xff0c;我们将对 Replicator 的核心功能 - “Hello World”中解…