C#基础--迭代器初识
foreach语句是枚举器(enumerator)的消费者,而迭代器(iterator)是枚举器的产生者。
迭代器模式能提供一种顺序访问一个集合内部的元素,而又不会暴露其内部的方法。当然其缺点就是用foreach语句遍历的同时,不能修改集合内部的元素。
我们已经在foreach语句中接触过了它 foreach (var item in collection) ,C#利用foreach实现了访问迭代器的内置支持。
实际上foreach被编译后会产生GetEnumerator和MoveNext方法,还有current属性。
一.C#2 便捷的语法糖
下面我们先来介绍C#2.0为实现迭代器提供的便捷语法。
先看两个单词的翻译 enumerator(枚举器) enumerable(可枚举类型)
下面举个例子:
using System;
using System.Collections;
using System.Collections.Generic; namespace ConsoleApp1
{ class Program
{
static IEnumerable<string> AddAB(int Count)
{
string str = "h";
for (int i = ; i < Count; i++)
{
yield return str;
str += "a";
}
Console.WriteLine("");
for (int i = ; i < Count; i++)
{
Console.WriteLine("before yoeld return "+str);
yield return str;
str += "b";
}
}
static void Main(string[] args)
{
foreach (var str in AddAB())
{
Console.WriteLine(str);
}
}
}
}

IEnumerable接口的GetEnumerator方法实现了IEnumerator枚举器类的实例。所以上文的代码是没问题的,后面会给大家示范用IEnumertor接口实现迭代器。
yield return语句的意思是你向我请求从枚举器产生的下一个元素。
每次执行到yield return就会返回到他调用者那,但还会执行yield return之后的语句,直到碰到下一条yield return时停止。这个状态一直持续到foreach语句的结束。
二.C#1 手写迭代器
再来看看这句话:foreach语句是枚举器(enumerator)的消费者,而迭代器(iterator)是枚举器的产生者。
【enumerator(枚举器) enumerable(可枚举类型)】
foreach需要获得一个enumerator,而我们需要用IEnumerator接口实现迭代器。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq; namespace ConsoleApp1
{
class Alp : IEnumerable
{
string[] value = { "a", "b", "c" };
public IEnumerator GetEnumerator()
{
return new AlpEnumerator(value);
}
}
class AlpEnumerator : IEnumerator
{
string[] alp;
int position = -;
public AlpEnumerator(string[] str)
{
alp = new string[str.Length];
for (int i = ; i < str.Length; i++)
{
alp[i] = str[i];
}
}
public object Current
{
get
{
if (position == -)
throw new InvalidOperationException();
if (position >= alp.Length)
throw new InvalidOperationException();
return alp[position];
}
} public bool MoveNext()
{
if (position < alp.Length - )
{
position++;
return true;
}
else
return false;
} public void Reset()
{
position = -;
}
}
class Program
{ static void Main(string[] args)
{
Alp alp = new Alp();
foreach (var item in alp)
{
Console.WriteLine(item);
}
}
}
}
- Current 获取当前位置
- MoveNext 判断是否可移动到下一位
- Reset 将位置重置为初始位置
C#基础--迭代器初识的更多相关文章
- python基础——迭代器
python基础——迭代器 我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是generator,包括生成器 ...
- python基础—迭代器、生成器
python基础-迭代器.生成器 1 迭代器定义 迭代的意思是重复做一些事很多次,就像在循环中做的那样. 只要该对象可以实现__iter__方法,就可以进行迭代. 迭代对象调用__iter__方法会返 ...
- java基础-迭代器(Iterator)与增强for循环
java基础-迭代器(Iterator)与增强for循环 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Iterator迭代器概述 Java中提供了很多个集合,它们在存储元素时 ...
- 316python 基础之计算机基础、Python简介、变量、注释、基础数据类型初识、if、while、语句
一.计算机基础. cpu:相当于人的大脑,运算与控制中心. 速度 飞机 内存:4G,8G,16G....暂时存储,供给cpu数据. 速度 高铁.成本高,断电即消失. 硬盘:相当于你电脑的数据库,存储着 ...
- 081 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 06 new关键字
081 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 06 new关键字 本文知识点:new关键字 说明:因为时间紧张,本人写博客过程中只是 ...
- 080 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 05 单一职责原则
080 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 05 单一职责原则 本文知识点:单一职责原则 说明:因为时间紧张,本人写博客过程中只是 ...
- 079 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 04 实例化对象
079 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 04 实例化对象 本文知识点:实例化对象 说明:因为时间紧张,本人写博客过程中只是对知 ...
- 078 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 03 创建类
078 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 03 创建类 本文知识点:创建类 说明:因为时间紧张,本人写博客过程中只是对知识点的关 ...
- 077 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 02 类和对象
077 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 02 类和对象 本文知识点:类和对象 说明:因为时间紧张,本人写博客过程中只是对知识点 ...
随机推荐
- IOC @Autowired/@Resource/@Qulified的用法实例
首先要知道另一个东西,default-autowire,它是在xml文件中进行配置的,可以设置为byName.byType.constructor和autodetect:比如byName,不用显式的在 ...
- java MVC 自定义类型转换器(Formatter、AnnotationFormatterFactory)
下面一个事例,是将传入的一个身份证号,转换成一个对象(提取身份证号的地址.出身日期.性别等) 实体类 Person 有三个字段如下: String province; //地址 Date birthd ...
- H2O theme for Jekyll
正如我在微博上所说的,使用Jekyll半年以来一直没有令我满意的主题模板,所以开始计划自己写一套好看又好用的主题模板.设计之初就明确了极简主义,风格采用扁平化了,通过卡片式设计来进行区块分明的布局,参 ...
- 谈谈从事IT测试行业的我,对于买房买车有什么样的感受
周边测试同事,开发同事买?买?的比较多, 偶尔大家话题中也会谈起这个. 毕竟工作.衣.食.住.行和我们每个IT从业者息息相关, 大家有着相同或相似的感受与经验. - 前公司 以前公司测试经理 10年从 ...
- Redis:slave flush old data造成实例不可用
一.问题描述 2019-02-22凌晨02:42分前后,收到集群中 [10.32.52.8:6500] 实例不可用告警,登陆管理界面查看此实例在正常运行状态,期间未出现机器宕机或实例直接挂掉的现象. ...
- Coding and Paper Letter(十五)
资源整理. 1.Nature Climate Change论文"Higher temperatures increase suicide rates in the United States ...
- javascript中变量命名规则
前言 变量的命名相对而言没有太多的技术含量,今天整理有关于变量命名相关的规则,主要是想告诉大家,虽然命名没有技术含量,但对于个人编码,或者说一个团队的再次开发及阅读是相当有用的.良好的书写规范可以让你 ...
- mysql长连接与短连接
什么是长连接? 其实长连接是相对于通常的短连接而说的,也就是长时间保持客户端与服务端的连接状态. 通常的短连接操作步骤是: 连接->数据传输->关闭连接: 而长连接通常就是: 连接-> ...
- 《Effective Java》笔记45-56:通用程序设计
将局部变量的作用域最小化,可以增强代码的可读性和可维护性,并降低出错的可能性. 要使用局部变量的作用域最小化,最有力的方法就是在第一次使用它的地方才声明,不要过早的声明. 局部变量的作用域从它被声明的 ...
- powershell加KeePass实现,加密服务器密码清单文件
powershell加KeePass实现,加密服务器清单文件 powershell传教士翻译,改写. 2020-02-27 原文: https://www.altaro.com/msp-doj ...