首页 > 编程语言 >C#快速入门(十):枚举

C#快速入门(十):枚举

时间:2024-06-23 21:28:00浏览次数:22  
标签:语句 遍历 入门 迭代 C# 元素 yield 枚举 集合

一、枚举

1.1 IEnumerator 接口

IEnumerator 接口是用于支持集合类的迭代的接口。它定义了用于访问集合中元素的成员,并提供了一种统一的方式来遍历集合中的元素。

IEnumerator 接口定义了以下成员:

  • Current 属性:获取集合中当前位置的元素。
  • MoveNext() 方法:将迭代器推进到集合中的下一个元素。
  • Reset() 方法:将迭代器重置到集合的开头。

使用 IEnumerator 接口遍历集合:

  • 要使用 IEnumerator 接口遍历集合,首先需要获取集合的 IEnumerator 对象,通常使用集合的 GetEnumerator() 方法来实现。
  • 调用 MoveNext() 方法将迭代器推进到集合中的下一个元素,并返回一个布尔值指示是否还有更多的元素可供遍历。
  • 使用 Current 属性获取当前位置的元素值。
  • 如果需要重新开始遍历,可以调用 Reset() 方法将迭代器重置到集合的开头。

以下是一个示例代码,演示了如何使用 IEnumerator 接口遍历集合:

ArrayList list = new ArrayList();
list.Add("Apple");
list.Add("Banana");
list.Add("Orange");

IEnumerator enumerator = list.GetEnumerator();

while (enumerator.MoveNext())
{
    string fruit = (string)enumerator.Current;
    Console.WriteLine(fruit);
}

enumerator.Reset();

while (enumerator.MoveNext())
{
    string fruit = (string)enumerator.Current;
    Console.WriteLine(fruit);
}

在上述示例中,我们创建了一个 ArrayList 集合,并向其中添加了几个元素。然后,我们使用集合的 GetEnumerator() 方法获取一个 IEnumerator 对象,用于遍历集合。

通过调用 MoveNext() 方法,我们将迭代器推进到集合中的下一个元素。在每次循环中,我们使用 Current 属性获取当前位置的元素值,并将其转换为 string 类型。

在第一个循环结束后,我们调用 Reset() 方法将迭代器重置到集合的开头。然后,再次使用 MoveNext() 和 Current 遍历集合,输出相同的元素。

需要注意的是,迭代器模式在遍历过程中通常会检测集合的结构是否发生了变化,以确保遍历的安全性。如果在遍历过程中修改了集合的结构(如添加、删除元素),可能会引发 InvalidOperationException 异常。因此,在使用迭代器遍历集合时,应注意避免修改集合的结构。

1.2 foreach 语句

foreach 语句是用于遍历集合或数组的循环结构。它提供了一种简洁的方式来逐个访问集合中的元素,而无需使用索引或迭代器。

语法:

foreach (var item in collection)
{
// 执行操作
}

item是一个变量,用于存储集合中的当前元素值。

  • collection 是一个实现了 IEnumerable 或 IEnumerable 接口的集合或数组。
  • 在循环体内,可以对 item 进行操作,访问集合中的元素。

foreach 语句的特点:

  • foreach 语句提供了一种简洁的方式来遍历集合或数组中的元素,无需使用索引或迭代器。
  • foreach 语句会自动处理集合的迭代过程,使得代码更加清晰和易读。
  • foreach 语句在循环开始时会自动获取集合的迭代器,并在每次迭代时更新当前元素。

foreach 语句的底层原理:

  • foreach 语句的底层实现依赖于 IEnumerable 接口和迭代器模式。
  • 集合类或数组类实现了 IEnumerable 或 IEnumerable 接口,该接口定义了 GetEnumerator() 方法,用于返回一个实现了 IEnumerator 或 IEnumerator 接口的迭代器对象。
  • foreach 语句在编译时会被转换为使用迭代器的代码,以实现对集合的遍历。
  • 在循环开始时,foreach 语句会调用集合的 GetEnumerator() 方法获取一个迭代器对象。
  • 然后,使用迭代器的 MoveNext() 方法将迭代器推进到集合中的下一个元素,并使用 Current 属性获取当前元素的值。
  • 在每次循环迭代中,循环体内的代码会对当前元素进行操作。
  • 当迭代结束时,或者遇到 break 语句时,循环退出。

需要注意的是,使用 foreach 语句遍历集合时,不应在循环过程中修改集合的结构(如添加、删除元素),否则可能会引发异常。foreach 语句在循环开始时获取了集合的迭代器,如果在迭代过程中修改了集合的结构,会导致迭代器失效,从而引发 InvalidOperationException 异常。

1.3 yield 语句

yield 语句用于创建迭代器(iterator),它提供了一种简洁的方式来实现可枚举类型(enumerable types)的迭代。通过使用 yield 语句,可以在迭代过程中逐个返回元素,而无需显式地实现迭代器的接口和方法。

语法:

  • yield 语句通常与一个迭代器方法(iterator method)一起使用。迭代器方法是一种特殊的方法,它使用 yield 语句来指示迭代过程的逻辑。
  • IEnumerable<T>:迭代器方法返回类型应为 IEnumerable<T>,表示它可以产生一个序列的元素。
  • yield return:使用 yield return 语句返回序列中的元素。可以在迭代过程中多次使用 yield return 语句返回多个元素。
  • yield break:使用 yield break 语句提前终止迭代,返回到调用代码。

迭代器方法的基本语法如下:

public IEnumerable<T> MyIterator()
{
    // 迭代逻辑
    yield return element;
}

yield 语句的特点:

  • 使用 yield 语句可以使迭代过程更加简洁和易读,避免了手动实现迭代器的复杂性。
  • yield 语句将迭代逻辑与产生序列的元素分离,使代码更加模块化和可维护。

yield 语句的底层原理:

  • yield 语句的底层原理基于状态机(state machine)的概念。
  • 当编译器遇到包含 yield 语句的迭代器方法时,它将生成一个状态机类(state machine class)来处理迭代逻辑。
  • 状态机类实现了 IEnumerator<T> 接口,并使用状态来追踪迭代过程。
  • 每次调用迭代器方法时,会创建一个状态机对象的实例,并返回该实例的迭代器。
  • 在每次调用迭代器的 MoveNext() 方法时,状态机根据当前状态执行相应的逻辑,并返回下一个元素的值。
  • 使用 yield return 语句返回元素时,状态机会将当前状态保存下来,并在下一次调用 MoveNext() 时继续执行。
  • 当遇到 yield break 语句或迭代结束时,状态机停止迭代,并将迭代器标记为结束。

下面是一个使用 yield 语句的简单示例,演示了如何使用 yield 语句来创建一个简单的迭代器方法:

static void Main(string[] args)
{
    foreach (var number in GetNumbers())
    {
        Console.WriteLine(number);
    }
}
public static IEnumerable<int> GetNumbers()
{
    yield return 1;
    yield return 2;
    yield return 3;
}

在上述示例中,GetNumbers() 方法是一个迭代器方法,返回类型为 IEnumerable<int>。通过使用 yield return 语句,每次迭代时返回一个整数元素。在 Main() 方法中,使用 foreach 循环来遍历迭代器方法返回的序列,并输出每个元素的值。
需要注意的是,使用 yield 语句创建的迭代器是惰性求值的。即在迭代过程中,元素是按需生成的,只有在调用者请求时才会计算和返回元素值。这种惰性求值的特性可以提高性能和节省内存,尤其在处理大型数据集时。

标签:语句,遍历,入门,迭代,C#,元素,yield,枚举,集合
From: https://blog.csdn.net/xhh0308/article/details/139283974

相关文章

  • allWebPlugin助力iWebOffice2015插件在高版本浏览器使用
    allWebPlugin简介   allWebPlugin中间件是一款为用户提供安全、可靠、便捷的浏览器插件服务的中间件产品,致力于将浏览器插件重新应用到所有浏览器。它将现有ActiveX插件直接嵌入浏览器,实现插件加载、界面显示、接口调用、事件回调等。支持谷歌、火狐等浏览器,接口调用友好......
  • python基础 - socket编程基础
    一对一---服务端importsocketip_port=('127.0.0.1',9999)1-创建socket对象---socket也叫套接字sk=socket.socket()2-绑定ip端口sk.bind(ip_port)3-开启监听sk.listen()print('---socket服务器已经启动完成---')4-阻塞等待客户端来链接可以返回连接对象......
  • 【java】解决EasyExcel读取InputStream时解析不到excel文件类型的问题
    正常利用EasyExcel读取excel中sheet时会调用如下接口:publicstaticExcelReaderBuilderread(StringpathName,ReadListenerreadListener){returnread((String)pathName,(Class)null,readListener);}publicstaticExcelReaderBuilderread(Stringp......
  • 力扣每日一题 美丽下标对的数目 枚举 哈希
    Problem:2748.美丽下标对的数目......
  • 全面掌握 CrystalDiskInfo使用教程 的各项高级功能,实现专业级别的硬盘健康管理、性能
    CrystalDiskInfo的初级应用大纲:介绍:CrystalDiskInfo是一款免费的硬盘健康监测工具,可以帮助用户监测硬盘状态,预测故障,并提供警报通知。安装和启动:下载并安装CrystalDiskInfo软件;启动CrystalDiskInfo软件。界面导览:主界面介绍:显示硬盘信息、健康状态、温度......
  • Spring Batch
    项目是做历史表的Migration锁定一定数量的历史表A,B,C,每张历史表在配置表里有一张记录,包括需要distinct的关键字段,包括分区大小,core大小(逻辑分区)以及一个参数(select_clause,历史表的条件比如时间)举例子,数据库配置表里 历史表A 的distinct字段country_code到60w条数据,分......
  • 58-DOS与DDOS分析(正常TCP会话与SYN Flood攻击、ICMP Flood 攻击、SNMP放大攻击等)
    目录正常TCP会话与SYNFlood攻击1、正常的三次握手过程:2、SYNFlood攻击一、攻击windows系统:二、攻击web网站:拒绝服务攻击工具-Hping3-SynFlood攻击拒绝服务攻击工具--Hping3--ICMPFlood攻击 sockstress攻击Sockstress防范 DNS放大攻击产生大流量的攻......
  • SDL3 入门(3):三角形
    SDL3提供了SDL_RenderGeometry函数绘制几何图形,用法和OpenGL差不多,先定义顶点数据,然后根据顶点数据绘制几何图形。绘制三角形的代码如下:std::array<SDL_Vertex,3>origin_vertices={SDL_Vertex{{150,100},{1.0f,0.0f,0.0f,1.0f}},//topSDL_Vert......
  • TCP与UDP_三次握手_四次挥手
    TCPvsUDPTCP数据具体可以通过CiscoPacketTracer工具查看:UDP数据三次握手、四次挥手为什么是3/4次?这牵扯到单工、双工通信的问题TCP建立连接:表白TCP释放连接:分手TCP—建立连接—三次握手解释:首先,启动服务器,让服务器进入监听状态(监听客户端的连接请......
  • 使用cloudflare-works搭建自己docker加速源
    在网上看到了许多教程,基本上部署都是手动的,docker镜像都要手动输入选择重新部署。要么都是些基本镜像仓库。视频地址:【CloudFlare搭建doker加速源。都这么长时间了,你的docker还是跑不通吗?】https://www.bilibili.com/video/BV1F533eHEsB/?share_source=copy_web&vd_source=0742......