windows C#-迭代器(下)

news/2024/12/2 23:09:10/
对泛型列表使用迭代器

在以下示例中,Stack<T> 泛型类实现 IEnumerable<T> 泛型接口。 Push 方法将值分配给类型为 T 的数组。 GetEnumerator 方法通过使用 yield return 语句返回数组值。

除了泛型 GetEnumerator 方法,还必须实现非泛型 GetEnumerator 方法。 这是因为从 IEnumerable 继承了 IEnumerable<T>。 非泛型实现遵从泛型实现的规则。

本示例使用命名迭代器来支持通过各种方法循环访问同一数据集合。 这些命名迭代器为 TopToBottom 和 BottomToTop 属性,以及 TopN 方法。

BottomToTop 属性在 get 访问器中使用迭代器。

static void Main()
{Stack<int> theStack = new Stack<int>();//  Add items to the stack.for (int number = 0; number <= 9; number++){theStack.Push(number);}// Retrieve items from the stack.// foreach is allowed because theStack implements IEnumerable<int>.foreach (int number in theStack){Console.Write("{0} ", number);}Console.WriteLine();// Output: 9 8 7 6 5 4 3 2 1 0// foreach is allowed, because theStack.TopToBottom returns IEnumerable(Of Integer).foreach (int number in theStack.TopToBottom){Console.Write("{0} ", number);}Console.WriteLine();// Output: 9 8 7 6 5 4 3 2 1 0foreach (int number in theStack.BottomToTop){Console.Write("{0} ", number);}Console.WriteLine();// Output: 0 1 2 3 4 5 6 7 8 9foreach (int number in theStack.TopN(7)){Console.Write("{0} ", number);}Console.WriteLine();// Output: 9 8 7 6 5 4 3Console.ReadKey();
}public class Stack<T> : IEnumerable<T>
{private T[] values = new T[100];private int top = 0;public void Push(T t){values[top] = t;top++;}public T Pop(){top--;return values[top];}// This method implements the GetEnumerator method. It allows// an instance of the class to be used in a foreach statement.public IEnumerator<T> GetEnumerator(){for (int index = top - 1; index >= 0; index--){yield return values[index];}}IEnumerator IEnumerable.GetEnumerator(){return GetEnumerator();}public IEnumerable<T> TopToBottom{get { return this; }}public IEnumerable<T> BottomToTop{get{for (int index = 0; index <= top - 1; index++){yield return values[index];}}}public IEnumerable<T> TopN(int itemsFromTop){// Return less than itemsFromTop if necessary.int startIndex = itemsFromTop >= top ? 0 : top - itemsFromTop;for (int index = top - 1; index >= startIndex; index--){yield return values[index];}}}
语法信息

迭代器可用作一种方法,或一个 get 访问器。 不能在事件、实例构造函数、静态构造函数或静态终结器中使用迭代器。

必须存在从 yield return 语句中的表达式类型到迭代器返回的 IEnumerable<T> 类型参数的隐式转换。

在 C# 中,迭代器方法不能有任何 in、ref 或 out 参数。

在 C# 中,yield 不是保留字,只有在 return 或 break 关键字之前使用时才有特殊含义。

技术实现

即使将迭代器编写成方法,编译器也会将其转换为实际上是状态机的嵌套类。 只要客户端代码中的 foreach 循环继续,此类就会跟踪迭代器的位置。

若要查看编译器执行的操作,可使用 Ildasm.exe 工具查看为迭代器方法生成的公共中间语言代码。

为类或结构创建迭代器时,不必实现整个 IEnumerator 接口。 编译器检测到迭代器时,会自动生成 IEnumerator 或 IEnumerator<T> 接口的 Current、MoveNext 和 Dispose 方法。

在 foreach 循环(或对 IEnumerator.MoveNext 的直接调用)的每次后续迭代中,下一个迭代器代码体都会在上一个 yield return 语句之后恢复。 然后继续下一个 yield return 语句,直至到达迭代器体的结尾,或直至遇到 yield break 语句。

迭代器不支持 IEnumerator.Reset 方法。 若要从头开始重新迭代,必须获取新的迭代器。 在迭代器方法返回的迭代器上调用 Reset 会引发 NotSupportedException。

迭代器的使用

需要使用复杂代码填充列表序列时,使用迭代器可保持 foreach 循环的简单性。 需执行以下操作时,这可能很有用:

在第一次 foreach 循环迭代之后,修改列表序列。

避免在 foreach 循环的第一次迭代之前完全加载大型列表。 一个示例是用于加载一批表格行的分页提取。 另一个示例是 EnumerateFiles 方法,该方法在 .NET 中实现迭代器。

在迭代器中封装生成列表。 使用迭代器方法,可生成该列表,然后在循环中产出每个结果。


http://www.ppmy.cn/news/1551868.html

相关文章

【ETCD】etcd中配置参数详解

详细记录etcd服务启动的各个参数 1、etcd成员相关的配置项 --name default 为该成员指定一个易读的名称。--data-dir ${name}.etcd 数据存储目录的路径。--wal-dir 用于存放专用WAL&#xff08;Write-Ahead Log&#xff09;的目录路径。--snapshot-count 100000 触发快照…

R 因子

R 因子 引言 在金融领域&#xff0c;风险管理和投资策略的优化一直是核心议题。传统的风险度量工具&#xff0c;如波动率、Beta系数等&#xff0c;虽然在一定程度上能够帮助投资者理解市场的波动和资产的相对风险&#xff0c;但它们往往无法全面捕捉到市场动态的复杂性。因此…

3.27【机器学习】第五章作业代码实现

5.1 使用线性函数作为激活函数时&#xff0c;因为在单元层和隐藏层&#xff0c;其单元值仍是输入值X的线性组合&#xff0c;只能表示线性关系&#xff0c;无法表示非线性关系。神经网络的优势在于能够学习和表示复杂的非线性关系。如果使用线性激活函数&#xff0c;神经网络只…

小红书矩阵运营:怎么通过多个账号来提升品牌曝光?

在如今的社交媒体环境中&#xff0c;小红书作为一个以分享生活方式、购物心得为主的平台&#xff0c;已经成为品牌营销的热土。尤其是通过“小红书矩阵”&#xff0c;品牌能够精准触达不同的用户群体&#xff0c;提升曝光度和转化率。那么&#xff0c;如何通过多个账号进行矩阵…

Uniapp 微信小程序内打开web网页

技术栈&#xff1a;Uniapp Vue3 简介 实际业务中有时候会需要在本微信小程序内打开web页面&#xff0c;这时候可以封装一个路由页面专门用于此场景。 在路由跳转的时候携带路由参数&#xff0c;拼接上web url&#xff0c;接收页面进行参数接收即可。 实现 webview页面 新…

vitess使用记录:vtctldclient,设置分表规则

继续探索未完成的事情。 vitess使用记录系列已经写了好几篇了&#xff0c;记录了在测试过程中遇到的各种问题。《vitess使用&#xff1a;从部署到go客户端连接查询》、《vitess使用记录&#xff1a;vtctldclient》、《vitess使用&#xff1a;基于源码运行vtctldclient工具》整…

设计模式学习之——策略模式

策略模式&#xff08;Strategy Pattern&#xff09;是一种行为型设计模式&#xff0c;它允许定义一系列算法&#xff0c;并将每个算法封装在独立的类中&#xff0c;使它们可以互相替换。策略模式通过将算法的使用与算法的实现分离&#xff0c;使得算法可以独立于客户端而变化。…

Webman中实现定时任务

文章目录 Webman中实现定时任务一、引言二、安装与配置1、安装Crontab组件2、创建进程文件3、配置进程文件随Webman启动4、重启Webman5、Cron表达式&#xff08;补充&#xff09;例子 三、使用示例四、总结 Webman中实现定时任务 一、引言 在现代的后端开发中&#xff0c;定时…