《c#高级编程》第2章C#2.0中的更改(三)——迭代器
一、概念
C#迭代器(Iterator)是一种特殊类型的方法,它使得在使用循环遍历数据集合时更加简单和有效。使用迭代器可以通过简单地定义迭代器方法来自动实现枚举器模式。
当您需要访问一个数据集合中的每个元素时,可以使用迭代器来遍历该集合。C#中的迭代器通过yield关键字实现。yield语句用于指示方法返回一个序列,并返回一系列值。这些值会被逐个返回到调用方,并且方法的当前状态会保留下来,以便下次调用时继续执行。
以下是一个使用迭代器的简单示例,其中展示了如何使用它来遍历整数数组:
```csharp
static IEnumerable<int> GetNumbers()
{
int[] numbers = { 1, 2, 3, 4, 5 };
foreach (int number in numbers)
{
yield return number;
}
}
```
在这个示例中,GetNumbers()方法返回一个IEnumerable<int>类型的迭代器。在foreach循环中,使用yield return语句依次返回数组中的每个数字。
使用迭代器有以下几个好处:
1. 简化代码结构:使用迭代器使得代码结构更加清晰、简洁。
2. 节省内存:由于迭代器只是逐个返回序列中的元素,所以可以大大减少内存的使用。
3. 延迟计算:当使用yield return语句时,元素是按需生成的,这意味着在需要时才会计算。这可以提高性能,并允许处理非常大的数据集合。
4. 支持Linq查询:由于迭代器实现了IEnumerable和IEnumerator接口,因此它们可以与Linq查询一起使用。
总之,C#迭代器是一种非常有用的工具,它使得遍历和操作数据集合变得更加简单、高效和灵活。通过使用yield关键字,可以轻松地定义自己的迭代器方法,并利用其强大的功能来提高代码质量和性能。
二、使用场景
以下是使用C#迭代器的经典场景和演示代码:
- 遍历集合数据
使用 C# 迭代器可以更方便地遍历一个集合中的所有元素,而不必事先知道集合的大小。
public class MyList<T> : IEnumerable<T>
{
private List<T> _list; public MyList()
{
_list = new List<T>();
} public void Add(T item)
{
_list.Add(item);
} public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i < _list.Count; i++)
{
yield return _list[i];
}
} IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
} // 使用 MyList 遍历元素
var list = new MyList<int>();
list.Add(1);
list.Add(2);
list.Add(3); foreach (var item in list)
{
Console.WriteLine(item);
} 输出结果:
1
2
3
- 实现延迟加载
使用 C# 迭代器可以实现延迟加载,也就是说只有在需要访问某个元素时才会去加载它,从而提高程序的性能和效率。
public class LazyDataLoader<T> : IEnumerable<T>
{
private Func<IEnumerable<T>> _dataLoader; public LazyDataLoader(Func<IEnumerable<T>> dataLoader)
{
_dataLoader = dataLoader;
} public IEnumerator<T> GetEnumerator()
{
foreach (var item in _dataLoader())
{
yield return item;
}
} IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
} // 使用 LazyDataLoader 延迟加载数据
var dataLoader = new LazyDataLoader<int>(() => Enumerable.Range(1, 100000)); foreach (var item in dataLoader)
{
Console.WriteLine(item);
} 输出结果:
1
2
...
99999
100000
- 处理大型数据集
如果数据集非常大,无法一次性全部加载到内存中,使用 C# 迭代器可以分批次地读取数据,从而降低内存消耗。
public class BigDataLoader<T> : IEnumerable<T>
{
private Func<IEnumerable<T>> _dataLoader;
private int _batchSize; public BigDataLoader(Func<IEnumerable<T>> dataLoader, int batchSize)
{
_dataLoader = dataLoader;
_batchSize = batchSize;
} public IEnumerator<T> GetEnumerator()
{
var buffer = new T[_batchSize];
var count = 0; foreach (var item in _dataLoader())
{
buffer[count++] = item; if (count == _batchSize)
{
for (int i = 0; i < count; i++)
{
yield return buffer[i];
} count = 0;
}
} for (int i = 0; i < count; i++)
{
yield return buffer[i];
}
} IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
} // 使用 BigDataLoader 分批次读取数据
var bigDataLoader = new BigDataLoader<int>(() => Enumerable.Range(1, 100000), 1000); foreach (var item in bigDataLoader)
{
Console.WriteLine(item);
}
输出结果:
1
2
...
99999
100000
- 实现自定义的遍历逻辑
有时候我们需要按照特定的顺序或方式遍历集合数据,使用 C# 迭代器可以方便地实现自定义的遍历逻辑。
public class EvenNumberGenerator : IEnumerable<int>
{
private int _start;
private int _end; public EvenNumberGenerator(int start, int end)
{
_start = start % 2 == 0 ? start : start + 1;
_end = end % 2 == 0 ? end : end - 1;
} public IEnumerator<int> GetEnumerator()
{
for (int i = _start; i <= _end; i += 2)
{
yield return i;
}
} IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
} // 使用 EvenNumberGenerator 遍历偶数
var evenNumbers = new EvenNumberGenerator(10, 20); foreach (var item in evenNumbers)
{
Console.WriteLine(item);
}
输出结果:
10
12
14
16
18
20
- 简化代码结构
使用 C# 迭代器可以简化代码结构,使得代码更加易读易懂,从而提高代码的可维护性和可读性。
public class FibonacciSequence : IEnumerable<int>
{
private int _count; public FibonacciSequence(int count)
{
_count = count;
} public IEnumerator<int> GetEnumerator()
{
int a = 0;
int b = 1; for (int i = 0; i < _count; i++)
{
yield return a; int temp = a;
a = b;
b = temp + b;
}
} IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
} // 使用 FibonacciSequence 生成斐波那契数列
var fibonacci = new FibonacciSequence(10); foreach (var item in fibonacci)
{
Console.WriteLine(item);
} 输出结果:
0
1
1
2
3
5
8
13
21
34
《c#高级编程》第2章C#2.0中的更改(三)——迭代器的更多相关文章
- javascript高级编程3第二章:在html中使用javascript
2.1 <script>元素 向html页面中插入javascript的主要方法,就是使用<script>元素.这个元素被加入到正式的html规范中.html4.01为< ...
- ASP.NET MVC5 高级编程 第5章 表单和HTML辅助方法
参考资料<ASP.NET MVC5 高级编程>第5版 第5章 表单和HTML辅助方法 5.1 表单的使用 5.1.1 action 和 method 特性 默认情况下,表单发送的是 HTT ...
- ASP.NET MVC5 高级编程 第3章 视图
参考资料<ASP.NET MVC5 高级编程>第5版 第3章 视图 3.1 视图的作用 视图的职责是向用户提供界面. 不像基于文件的框架,ASP.NET Web Forms 和PHP ,视 ...
- ASP.NET MVC5 高级编程 第2章 控制器
参考资料<ASP.NET MVC5 高级编程>第5版 第2章 控制器 控制器:响应用户的HTTP 请求,并将处理的信息返回给浏览器. 2.1 ASP.NET MVC 简介 MVC 模式中的 ...
- UNIX环境高级编程 第8章 进程控制
本章是UNIX系统中进程控制原语,包括进程创建.执行新程序.进程终止,另外还会对进程的属性加以说明,包括进程ID.实际/有效用户ID. 进程标识 每个进程某一时刻在系统中都是独一无二的,它们之间是用一 ...
- 【读书笔记】C#高级编程 第五章 泛型
(一)泛型概述 泛型不仅是C#编程语言的一部分,而且与程序集中的IL代码紧密地集成.泛型不仅是C#语言的一种结构,而且是CLR定义的.有了泛型就可以创建独立于被包含类型的类和方法了. 1.性能 泛型的 ...
- 第四章 在MVC4.0中对脚本以及样式表的引用变化
原文:http://www.cnblogs.com/xdotnet/archive/2012/07/21/aspnet40_webpage20.html 一.可以直接使用“~”,而无需使用Href对象 ...
- C#高级编程第1章-.NET体系结构
内容提要: (1)编译和运行面向对象.NET代码 (2)IL/MSIL(Microsoft Intermediate Language)中间语言的优点 (3)值类型与引用类型 (4)数据类型化 (5) ...
- C#高级编程第2章-核心C#
内容提要: 声明变量:变量的初始化和作用域:C#的预定义数据类型:在C#程序中使用条件语句.循环和跳转语句指定执行流:枚举:名称空间: Main()方法:基本命令行C#编译器选项:使用System.C ...
- UNIX环境高级编程 第13章 守护进程
守护进程daemon是一种生存周期很长的进程.它们通常在系统引导时启动,在系统关闭时终止.守护进程是没有终端的,它们一直在后台运行. 守护进程的特征 在Linux系统中,可以通过命令 ps -efj ...
随机推荐
- Zabbix与乐维监控对比分析(三)——对象管理篇
大家好,我是乐乐.今天就不更新zabbix6.0的使用教程了.在前面的文章中,我们详细介绍了Zabbix与乐维监控在架构.性能.Agent管理.自动发现.权限管理等方面的对比分析,本篇是Zabbix对 ...
- java.lang.Long cannot be cast to java.util.Map-Oracle查询异常处理
Map<String, Object> map一.问题由来 测试环境中进行测试时,某一个接口频繁报一个错,java.lang.Long cannot be cast to java.uti ...
- great [ɡreɪt] ɡr 然后 eɪt 单词发音 r和前面的辅音连读
great [ɡreɪt] ɡr 然后 eɪt 单词发音 r和前面的辅音连读
- 【深度学习基础】基于Numpy的循环神经网络实现和反向传播训练
本文是<深度学习进阶:自然语言处理>.<神经网络与深度学习>和<动手学深度学习>的读书笔记.本文将介绍基于Numpy的循环神经网络的前向传播和反向传播实现,包括RN ...
- Java反序列化学习
前言 早知前路多艰辛,仙尊悔而我不悔.Java反序列化,免费一位,开始品鉴,学了这么久web,还没深入研究Java安全,人生一大罪过.诸君,请看. 序列化与反序列化 简单demo: import ja ...
- 3DCAT为华东师大设计学院打造元宇宙数字虚拟学院
6月11日,华东师范大学设计学院在chi K11美术馆举办了一场别开生面的 2023 年本科毕业设计暨项目实践教学现场演示展.其中,元宇宙数字虚拟学院(一期)的现场发布会引起了现场震撼,吸引了众多观众 ...
- Walrus 0.6发布:预览资源变更、丰富公有云支持,满足企业多云需求
近日,数澈软件Seal(以下简称"Seal")宣布基于 IaC 的开源应用管理平台 Walrus 0.6 正式发布! 在之前的版本中,Walrus 引入应用模型并优化了应用部署体验 ...
- python基础三(数据类型)
一 引子 1 什么是数据? x=10,10是我们要存储的数据 2 为何数据要分不同的类型 数据是用来表示状态的,不同的状态就应该用不同的类型的数据去表示 3 数据类型 数字(整形,长整形,浮点型,复数 ...
- 记录--Vue3+TS(uniapp)手撸一个聊天页面
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 Vue3+TS(uniapp)手撸一个聊天页面 前言 最近在自己的小程序中做了一个智能客服,API使用的是云厂商的API,然后聊天页面.. ...
- 记录--开局一张图,构建神奇的 CSS 效果
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 假设,我们有这样一张 Gif 图: 利用 CSS,我们尝试来搞一些事情. 图片的 Glitch Art 风 在这篇文章中 --CSS 故障 ...