[C#.NET 拾遗补漏]07:迭代器和列举器

阅读本文大概需要 3 分钟。

大家好,这是 [C#.NET 拾遗补漏] 系列的第 07 篇文章。

在 C# 中,大多数方法都是通过 return 语句立即把程序的控制权交回给调用者,同时也会把方法内的本地资源释放掉。而包含 yield 语句的方法则允许在依次返回多个值给调用者的期间保留本地资源,等所有值都返回结束时再释放掉本来资源,这些返回的值形成一组序列被调用者使用。在 C# 中,这种包含 yield 语句的方法、属性或索引器就是迭代器。

迭代器中的 yield 语句分为两种:

  • yeild return,把程序控制权交回调用者并保留本地状态,调用者拿到返回的值继续往后执行。

  • yeild break,用于告诉程序当前序列已经结束,相当于正常代码块的 return 语句(迭代器中直接使用 return 是非法的)。

下面是一个用来生成斐波纳契序列的迭代器示例:

IEnumerable<int> Fibonacci(int count)
{int prev = 1;int curr = 1;for (int i = 0; i < count; i++){yield return prev;int temp = prev + curr;prev = curr;curr = temp;}
}void Main()
{foreach (int term in Fibonacci(10)){Console.WriteLine(term);}
}

输出:

1
1
2
3
5
8
13
21
34
55

实际场景中,我们一般很少直接写迭代器,因为大部分需要迭代的场景都是数组、集合和列表,而这些类型内部已经封装好了所需的迭代器。比如 C# 中的数组之所以可以被遍历是因为它实现了 IEnumerable 接口,通过 GetEnumerator() 方法可以获得数组的列举器 Enumerator,而该列举器就是通过迭代器来实现的。比如最常见的一种使用场景就是遍历数组中的每一个元素,如下面逐个打印数组元素的示例。

int[] numbers = { 1, 2, 3, 4, 5 };
IEnumerator enumerator = numbers.GetEnumerator();
while (enumerator.MoveNext())
{Console.WriteLine(enumerator.Current);
}

其实这就是 foreach 的工作原理,上面代码可以用 foreach 改写如下:

int[] numbers = { 1, 2, 3, 4, 5 };
foreach (int number in numbers)
{Console.WriteLine(number);
}

当然,列举器不一定非要通过迭代器实现,例如下面这个自定义的列举器 CoffeeEnumerator。

public class CoffeeCollection : IEnumerable
{private CoffeeEnumerator enumerator;public CoffeeCollection(){enumerator = new CoffeeEnumerator();}public IEnumerator GetEnumerator(){return enumerator;}public class CoffeeEnumerator : IEnumerator{string[] items = new string[3] { "espresso", "macchiato", "latte" };int currentIndex = -1;public object Current{get{return items[currentIndex];}}public bool MoveNext(){currentIndex++;if (currentIndex < items.Length){return true;}return false;}public void Reset(){currentIndex = 0;}}
}

使用:

public static void Main(string[] args)
{foreach (var coffee in new CoffeeCollection()){Console.WriteLine(coffee);}
}

理解迭代器和列举器可以帮助我们写出更高效的代码。比如判断一个 IEnumerable<T> 对象是否包含元素,经常看到有些人这么写:

if(enumerable.Count() > 0)
{// 集合中有元素
}

但如果用列举器的思维稍微思考一下就知道,Count() 为了获得集合元素数量必然要迭代完所有元素,时间复杂度为 O(n)。而仅仅是要知道集合中是否包含元素,其实迭代一次就可以了。所以效率更好的做法是:

if(enumerable.GetEnumerator().MoveNext())
{// 集合中有元素
}

这样写时间复杂度是 O(1),效率显然更高。为了书写方便,C# 提供了扩展方法 Any()

if(enumerable.Any())
{// 集合中有元素
}

所以如有需要,应尽可能使用 Any 方法,效率更高。

再比如在 EF Core 中,需要执行 IQueryable<T> 查询时,有时候使用 AsEnumerable() 比使用 ToList、ToArray 等更高效,因为 ToList、ToArray 等会立即执行列举操作,而 AsEnumerable() 可以把列举操作延迟到真正被需要的时候再执行。当然也要考虑实际应用场景,Array、List 等更方便调用者使用,特别是要获取元素总数量、增删元素等这种操作。

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

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

相关文章

7-1 作业调度算法--先来先服务 (30 分)(思路+详解+vector+map+map做法)Come Baby!!!!!!!!!!!

一&#xff1a;题目&#xff1a; 输入N(N>0)个作业&#xff0c;输入每个作业的名字&#xff0c;到达时间&#xff0c;服务时间&#xff0c;按照先来先服务算法&#xff0c;计算每个作业的完成时间&#xff0c;周转时间&#xff0c;带权周转时间&#xff08;保留2位小数&…

html位置下移像素点,吃透移动端 1px的具体用法

最近在写移动端 H5 应用&#xff0c;遇到一个值得记录下来的点。现在从它的由来到实现&#xff0c;我们来聊一下移动端 1px&#xff0c;说 1px 不够准确&#xff0c;应该说成 1 物理像素 。通过阅读下面文章&#xff0c;你将会理解以下问题&#xff1a;问题为什么有 1px 这个问…

腾讯招.NET,居然要求精通MySQL,而不是SQLServer!

Docker、K8S、DevOps、微服务、云原生是这几年最火的技术名词&#xff0c;也是互联网的技术发展方向&#xff0c;.NET CoreMySQL的开源跨平台解决方案是.NET领域的不二之选&#xff01;然而大多数开发者甚至架构师&#xff0c;都聚焦在.NET Core上&#xff0c;以至于在MySQL性能…

7-2 作业调度算法--短作业优先 (30 分)(思路+详解+vector容器做法)Come Baby!!!!!!!!!!!

一&#xff1a;题目 输入N&#xff08;N>0&#xff09;个作业&#xff0c;输入每个作业的名字&#xff0c;到达时间&#xff0c;服务时间&#xff0c;按照短作业优先算法&#xff0c;计算每个作业的完成时间&#xff0c;周转时间&#xff0c;带权周转时间&#xff08;保留2…

android 手机交互设计,移动设备交互设计比较

以下为《移动设备交互设计比较》的无排版文字预览&#xff0c;完整内容请下载移动设备交互设计比较Base on Android、PPC、Symbian Ethanshao内部文档&#xff0c;请勿外传AndroidWindows Mobile 6.5Symbian S60 V5以联想乐Phone交互设计为例1UI Framework(交互框架)桌面布局 应…

程序员过关斩将--Http请求中如何保持状态?

微信搜一搜架构师修行之路这是一个被无数程序员撸过的问题&#xff0c;却只有少数人了解了真相。大体上搜了一下&#xff0c;网上关于http协议保持状态误导大家的文章还是有的&#xff0c;比如&#xff1a;有人说利用ViewState&#xff0c;那是asp.net下独有的东西&#xff0c;…

7-3 作业调度算法--高响应比优先 (40 分)(思路+详解+vector容器做法)Come Baby!!!!!

一&#xff1a;题目 输入N(N>0)个作业&#xff0c;输入每个作业的名字&#xff0c;到达时间&#xff0c;服务时间&#xff0c;按照高响应比优先算法&#xff0c;计算每个作业的完成时间&#xff0c;周转时间&#xff0c;带权周转时间&#xff08;保留2位小数&#xff09;。…

html css图标怎么跟文字并排,html - FA图标和文字环绕的HTML / CSS问题 - SO中文参考 - www.soinside.com...

我试图找到在Font Awesome Icon旁边写文本的正确方法。我希望文本在图标旁边排成一行&#xff0c;当文本被加长(或显示宽度缩短)时&#xff0c;我想在多行文本中而不是图标下面的图标旁边。TitleHeaderThis icon is a picture of a house. I want the text to wrap square so i…

基于C#开发的浏览器隐身工具-上班别乱开

魔鱼斯拉鹏_隐身高速浏览器是首款基于新款Chromium打造的超轻量“隐身”浏览器。采用时下流行的车机交互系统&#xff0c;主打“小透明”隐身访问功能&#xff0c;有了他你就可以&#xff08;上班&#xff09;肆意的开车遨游互联网了。测一测你的版本&#xff1a;https://liula…

vector容器中关于处理从非0位置开始赋值的操作

一&#xff1a;前言 问题描述&#xff1a;我们想从下标非0的位置开始赋值&#xff0c; 那么我们需要两步骤&#xff1a;1.确定开启的vector容器的范围(eg: vector v(1000)) 2.在赋值的时候&#xff0c;不可以用push_back()了&#xff0c;直接用&#xff08;v[i] values&…

html标签属性%= %,HTML标签属性集合

HTML标签属性集合更新时间&#xff1a;2017/2/8 10:28:00 浏览量&#xff1a;594 手机版图象热点映射范围锚&#xff0c;为文档定义连接首字母缩写词地址块引用放大字体为文档中的其他锚定义基本URL取代dir设置换行粗体在表单中创建一个按钮元素程序代码片段对某个文献引用定…

435. 无重叠区间(贪心经典题+思路+详解)

一&#xff1a;题目&#xff1a; 给定一个区间的集合&#xff0c;找到需要移除区间的最小数量&#xff0c;使剩余区间互不重叠。 注意: 可以认为区间的终点总是大于它的起点。 区间 [1,2] 和 [2,3] 的边界相互“接触”&#xff0c;但没有相互重叠。 示例 1: 输入: [ [1,2],…

UEFI + GPT 启动 VHD

说明 周五&#xff0c;笔记本充不进电了&#xff0c;还好我的系统是做到 VHD 中的&#xff0c;把硬盘拿出来&#xff0c;插到其它机器上&#xff0c;从我的硬盘启动就可以了&#xff08;虽然当时没有从我的系统启动&#xff0c;因为只需要等待一天&#xff0c;周末就可以去修电…

html列表变成三个一行,HTML列表仅限第一行缩进

将文本包装到项目符号右侧的原因是浏览器将整个list-item元素呈现在项目符号的右侧。它将始终将文本包装在包含文本的元素中。最简单的解决方案是不使用内置列表项目项目符号。取而代之的是创建一个你喜欢的子弹的图像并使用float&#xff1a;left将它放在左上角。文本将围绕它…

vector容器中重写sort方法

一&#xff1a;问题描述 1&#xff1a; 我们常用的vector中sort方法是升序的但我们可以通过重新定义sort方法即可实现其的降序处理&#xff0c;以前总是在结构体数组当中用到过重写sort方法&#xff0c;但其实在vector当中也是可以用的 2&#xff1a; 我们在调用的时候注意…

基于Prometheus和Grafana打造业务监控看板

前言 业务监控对许许多多的场景都是十分有意义&#xff0c;业务监控看板可以让我们比较直观的看到当前业务的实时情况&#xff0c;然后运营人员可以根据这些情况及时对业务进行调整操作&#xff0c;避免业务出现大问题。老黄曾经遇到过一次比较尴尬的“事故”。其中一条业务线&…

广西高考成绩查询2021,2021年广西高考个人排名怎么查询,广西高考成绩排名查询方法...

高考成绩公布后&#xff0c;很多家长和学生咨询我们&#xff0c;广西高考个人成绩排名位次如何查询&#xff1a;广西高考成绩排名&#xff0c;可以通过省招生考试院发布的广西一分一段表来查询&#xff0c;也可以到聚志愿网站直接输入分数查询&#xff0c;一分一段它显示每一个…

452. 用最少数量的箭引爆气球(贪心算法+思路+详解)07

一&#xff1a;题目 在二维空间中有许多球形的气球。对于每个气球&#xff0c;提供的输入是水平方向上&#xff0c;气球直径的开始和结束坐标。由于它是水平的&#xff0c;所以纵坐标并不重要&#xff0c;因此只要知道开始和结束的横坐标就足够了。开始坐标总是小于结束坐标。…

行为型设计模式总结

行为型设计模式总结Intro行为型模式是将不同的行为代码解耦&#xff0c;从而解决特定场景问题的一些经典结构。行为型设计模式主要解决的就是“类或对象之间的交互”问题。行为型设计模式比较多&#xff0c;有 11 个&#xff0c;几乎占了 23 种经典设计模式的一半。它们分别是&…

地理生物高考成绩查询2021,2021北京中考地理生物成绩查询时间【已公布】

中考地理和生物成绩查询是什么时候呢&#xff1f;尚不了解的考生看过来&#xff0c;下面由出国留学网小编为你精心准备了“2021北京中考地理生物成绩查询时间【已公布】”&#xff0c;持续关注本站将可以持续获取更多的考试资讯!2021北京中考地理生物成绩查询时间【已公布】北京…