C#枚举器和迭代器

news2024/9/28 5:26:10

C#枚举器和迭代器

使用foreach语句时,可以依次取出数组里面的元素,原因就是数组提供了“枚举器(Enumerator)”,枚举器知道元素的位置并返回请求项。

枚举器IEnumerator

枚举器实现了IEnumerator接口,该接口中有Current属性、MoveNext和Reset方法,foreach实现原理类似如下代码:

static void Main(string[] args)
{
    int[] MyArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    //可枚举类实现了GetEnumerator方法,获取枚举器
    IEnumerator ie = MyArray.GetEnumerator();
    while ( ie.MoveNext())
    {
        int i = (int)ie.Current;
        Console.WriteLine(i);
    }
}

示例

  1. 定义一个可枚举类
class Colors : IEnumerable
{
    string[] colors = { "blue", "red", "yellow" };

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

  1. 定义可枚举类中使用到的枚举器
class ColorEnumerator : IEnumerator
{
    string[] colors;
    int positon = -1;
    public ColorEnumerator(string[] colors)
    {
        this.colors = colors;
        for (int i = 0; i < colors.Length; i++)
        {
            this.colors[i] = colors[i];
        }
    }

    public object Current
    {
        get
        {
            if (positon == -1 || positon >= colors.Length) throw new InvalidOperationException();
            return colors[positon];
        }
    }

    public bool MoveNext()
    {
        if(positon <colors.Length-1)
        {
            positon++;
            return true;
        }
        else
        {
            return false;
        }
    }

    public void Reset()
    {
        positon = -1;
    }
}
  1. 使用可枚举类
static void Main(string[] args)
{
    Colors colors = new Colors();
    foreach (var item in colors)
    {
        Console.WriteLine(item);
    }
    Console.Read();
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n0cvT8KQ-1672824371803)(C#枚举器和迭代器.assets/image-20230104164933735.png)]

泛型枚举器

IEnumerator<T>

泛型枚举器与普通枚举器类似,不同之处在于普通枚举器的Current属性是Object类型,在取出是需要进行转化(看上面while代码块中的代码),而泛型可以直接返回指定的类型。

迭代器

迭代器使用

迭代器简化了可枚举器和可枚举类型的编码工作。yield return 表示依次返回枚举中的下一项。

如何要实现上面的实例,只需要实现可枚举类:

class Colors 
{
    string[] colors = { "blue", "red", "yellow" };

    public IEnumerator GetEnumerator()
    {
        return GetColorsEnumerator();
    }
	//返回枚举器
    public  IEnumerator<string> GetColorsEnumerator()
    {
        yield return "blue";
        yield return "red";
        yield return "yellow";
    }
}

结果与上面示例完全相同

常见迭代器模式

  1. 迭代器返回枚举器
class Colors
{
    public IEnumerator GetEnumerator()
    {
        return GetColors();
    }
	//该出返回的是枚举器
    public  IEnumerator<string> GetColors()
    {
        yield return ..;
        yield return ..;
        ...
    }
}
Colors colors = new Colors();
foreach (var item in colors)
{
     Console.WriteLine(item);
}
  1. 迭代器返回可枚举类型
class Colors
{
    //可以选择不实现该方法,让Colors类变成不可枚举类
    public IEnumerator GetEnumerator() 
    {
        return GetColors().GetEnumerator();
    }
	//该出返回的是可枚举类型
    public  IEnumerable<string> GetColors()
    {
        yield return ..;
        yield return ..;
        ...
    }
}
Colors colors = new Colors();
//如果实现GetEnumerator()方法,则使用以下方法
foreach (var item in colors)
{
     Console.WriteLine(item);
}
//如果没有实现GetEnumerator()方法,则使用以下方法
foreach (var item in colors.GetColors())
{
     Console.WriteLine(item);
}

多个迭代器

上面讲的迭代器有两种模式,为什么需要第2种方式?答案时候第2中方式更加灵活,比如可以实现多个迭代器

class Colors 
{
    string[] colors = { "blue", "red", "yellow" };


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

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

使用

static void Main(string[] args)
{
    Colors colors = new Colors();
    foreach (var item in colors.A())
    {
        Console.WriteLine(item);
    }
    Console.WriteLine("--------------");
    foreach (var item in colors.B())
    {
        Console.WriteLine(item);
    }
    Console.Read();
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sj2pmDOe-1672824371804)(C#枚举器和迭代器.assets/image-20230104172159795.png)]

迭代器作为属性

上面的迭代器是作为方法,可以将方法封装为属性,方便调用

class Colors
{
    string[] colors = { "blue", "red", "yellow" };


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

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

使用方式基本相同,只不过是将方法调用改成了属性

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

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

相关文章

Angular页面使用指令和路由守卫进行权限控制

在各种业务系统中&#xff0c;为了保证业务及数据安全&#xff0c;除了要求用户必须登录后才能操作外&#xff0c;还针对不同的角色对不同用户设置了各自的访问权限&#xff0c;包括确定的某个页面的权限和页面中特定元素的权限。本文记录了一种Angular页面常用的权限管理方法。…

C++:std::function模板类

一&#xff1a;function定义 类模板 std::function是一种通用的多态函数包装器&#xff0c;它的实例可以对任何可以调用的目标实体进行存储&#xff0c;复制和调用操作。简单的来说&#xff1a;C中有几种可调用对象&#xff1a;函数&#xff0c;指针&#xff0c;lambda表达式&…

区块链之开发命令行操作模块

文章目录功能介绍go语言中flag用法简介项目命令行具体实现链接&#xff1a; 区块链项目github地址项目目前进度&#xff1a;功能介绍 利用命令行操作区块链相较于图形用户界面来说&#xff0c;编写代码简单&#xff0c;同时也可以实现复杂的功能。命令行模块的功能应该满足&am…

Java学习笔记 --- JDBC(1)

一、JDBC概述 基本介绍 1、JDBC为访问不同的数据库提供了统一的接口&#xff0c;为使用者屏蔽了细节问题 2、Java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统&#xff0c;从而完成对数据库的各种操作 3、JDBC原理图 JDBC带来的好处 JDBC是Java提供一套用于数…

安卓移动端调用自然语言处理nlp模型【示例+源码】

安卓可以使用许多不同的方法来调用NLP模型。其中一种方法是使用现有的自然语言处理库,例如 Apache OpenNLP、 Stanford NLP 和 NLTK。这些库提供了许多常用的 NLP 功能,如分词、词干化、命名实体识别和词性标注。另一种方法是使用 TensorFlow Lite 或其他机器学习框架来加载并…

[ins 2022] 针对已见和未见群体的群体推荐中的贝叶斯归纳学习

Bayesian inductive learning in group recommendations for seen and unseen groupshttps://www.sciencedirect.com/science/article/pii/S0020025522008933摘要群组推荐是指向一组用户&#xff08;即成员&#xff09;推荐物品。在预测相关项目时&#xff0c;模型通常会面临未…

fs 文件系统模块

1、什么是 fs 文件系统模块 fs 模块是 Node.js 官方提供的、用来操作文件的模块。它提供了一系列的方法和属性&#xff0c;用来满足用户对文件的操作需求。 方法名 说明 fs.readFile() 用来读取指定文件中的内容 fs.writeFile() 用来向指定的文件中写入内容 如果要在 J…

webflux整合swagger教程V2版

1. yml文件配置 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId><version>2.1.0.RELEASE</version></dependency><!--数据库开始--&…

python @classmethod

1..什么是classmethod classmethod是用来指定一个类的方法为类方法 长的像下面这个样子 1 2 3 class cc: classmethod def f(cls, arg1, arg2, ...): ... cls通常用作类方法的第一参数 跟self有点类似&#xff08; __init__里面的slef通常用作实例方法的第一参数)。…

vue开发环境配置Visual Studio Code配置和安装教程

方便前端vue开发&#xff0c;使用vs code插件安装详细教程&#xff0c;关于vs code可以网络上相关的教程&#xff0c;插件安装如下图所示&#xff0c;大家常用的插件可再分享&#xff0c;与我联系。 1 安装Vue语法高亮显示插件&#xff1a;vetur 2 安装vue语法提示插件&#xf…

小孩上了半年小学,针对老师的评语总结,如何对症优化教育培养策略?chatGPT搜了一下,AI震惊了我

评语 班主任评语&#xff1a; 你是一个性格内向、聪明伶俐的男孩。平时能按时完成老师布置的作业&#xff0c;学习认真&#xff0c;成绩优良&#xff0c;做事认真。但有时自己的事情还不能自己完成&#xff0c;希望你以后可以独立起来&#xff0c;遇到问题多想办法&…

高性能网关基石——OpenResty

什么是 OpenRestyOpenResty 一个基于 Nginx 的高性能 Web 平台&#xff0c;能够方便地搭建处理超高并发的动态 Web 应用、 Web 服务和动态网关。例如有名的 Kong 网关和国产新秀 ApiSIX 网关都是基于 OpenResty 来进行打造的。OpenResty 通过实现 ngx_lua 和 stream_lua 等 Ngi…

Nmap工具使用

Nmap工具使用1.Nmap简介1.1.Nmap介绍1.2.Nmap功能介绍1.3.Nmap下载1.4.Nmap端口状态2.Nmap基本使用2.1.Nmap基础扫描2.2.Nmap基础扫描多个目标2.3.Nmap详细扫描输出2.4.Nmap指定端口扫描2.4.1.单端口扫描2.4.2.端口范围扫描2.4.3.端口组合扫描2.5.Nmap扫描排除2.5.1.排除一个主…

强大的ANTLR4(6)--设计语法

四种抽象的计算机语言模式&#xff1a; 1&#xff09;序列&#xff1a;一列元素&#xff0c;数组 2&#xff09;选择&#xff1a;在多个可选方案中做出选择 3&#xff09;词法符号依赖&#xff1a;例如左右括号匹配 4&#xff09;嵌套结构&#xff1a;一种自相似的语言结构。 …

lambda表达式入门

一、函数式编程思想 1 概念 面向对象思想需要关注用什么对象完成什么时期&#xff0c;而函数式编程思想更类似于我们数学中的函数&#xff0c;它主要关注的是对数据进行了什么操作 2 优点 代码简洁&#xff0c;开发快速接近自然语言&#xff0c;易于理解易于"并发编程…

计算机网络——BGP协议

BGP协议 和谁交换&#xff1a;与其他AS的邻站BGP发言人交换信息。 交换什么&#xff1a;交换网络可达性信息 多久交换一次&#xff1a;发生变化时更新有变化的部分 一般来说两个网络都是由一个BGP发言人连接的。 BGP协议交换信息的过程 BGP协议所交换的网络可达性的信息就…

Haproxy 代理后端服务

参考 http://www.haproxy.org HAProxy GitHub 目录 一、Haproxy环境准备 1、Haproxy简介 1.1、haproxy原理 1.2、Haproxy优点 2、在线apt安装 二、使用Haproxy 1、基本脚本结构示例 2、配置反向代理 3、验证haproxy 3.1、重启服务 3.2、访问后台管理 3.3、访问…

Linux下用gdb定位Qt程序崩溃位置(systemd-coredump)

目录1. systemd-coredump2. 用gdb定位崩溃位置Linux提供了systemd-coredump服务&#xff0c;可以配合gdb来定位到程序崩溃位置&#xff0c;下面介绍它们的用法。1. systemd-coredump systemd-coredump的简单介绍&#xff1a; systemd-coredump能从操作系统内核中获取内存转储&…

IDEA2022.1创建Maven web项目 + SpringMVC入门学习

SpingMVC 入门案例 文章目录SpingMVC 入门案例项目的结构1.导入SpringMVC和Servlet依赖2.创建SpringMVC控制器类&#xff08;等同Servlet&#xff09;3.初始化SpingMVC环境&#xff08;同Spring环境&#xff09;&#xff0c;设定SpringMVC加载对应的bean4.创建web容器启动类&am…

MWORKS.Sysplorer基于数据字典管理模型参数应用案例

1 引言 在面向微控制器的建模过程中&#xff0c;控制算法是可以复用到不同型号的同类产品中的。为了提高控制算法的可移植性&#xff0c;需要将模型与数据分开管理。如果不将模型与数据分开管理&#xff0c;直接将数据保存到模型中&#xff0c;即使在非批产的工程化应用或者小…