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 类和对象 本文知识点:类和对象 说明:因为时间紧张,本人写博客过程中只是对知识点 ...
随机推荐
- HTMLTestRunner测试报告
把测试报告写入文件中,设置报告生成的路径 测试报告名称上添加时间 HTMLTestRunner文件如下,复制即可用,把该文件放在Lib下即可 """ A TestRunn ...
- 使用Connector / Python连接MySQL/查询数据
使用Connector / Python连接MySQL connect()构造函数创建到MySQL服务器的连接并返回一个 MySQLConnection对象 在python中有以下几种方法可以连接到M ...
- LeetCode Problem 90. Subsets II
python solution 123456789101112131415161718192021222324252627 class (object): def subsetsWithDup(sel ...
- JAVA学习大纲
1.第一节 JAVA概念与JDK的安装 (1)JDK的安装和环境变量的设置: (2)相关基本概念:JDK.SDK.JRE.JVM.J2SE.J2EE.J2ME.java API.JAVA语言特点: ( ...
- Django 学习笔记1-- URLconf
今天好像巴黎有点乱,希望明天太阳还会照常升起. 简介 Django 是一个由 Python 编写.开源并采用经典的 MVC 设计模式的 Web Full Stack 应用框架. 在 Django 中, ...
- Circles of Waiting
题目传送门 很容易列出期望的方程,高斯消元搞一波但是常规消元复杂度是$O(r^6)$的考虑从左到右从上到下编号然后按编号从小到大消元假设黄点是已经消元的点,那么消下一个点的时候,只有绿点的方程中该项系 ...
- 脚本化处理linux云服务器第二硬盘初始化
#!/usr/bin/bash # 可以带参数 method=$ size=$ mydir=$ [ $#== ]&&{ echo -e "Missing parameter! ...
- shell编程1:变量的使用与例子
一.Shell脚本的执行通常可以采用以下几种方式: 1):bash script-name或sh script-name(推荐使用) 2):path/script-name 或./script-nam ...
- 自定义 ---UICollectionViewLayout-正N变形居中布局
1. 自定义UICollectionLayout ---- 正三角形居中布局 支持多个图形的自动布局 2. 自定义UICollectionLayout ---- 正方形居中布局 滚动展示的区域 3. ...
- Grafana使用总结
最近工作需求学习了下grafana,根据创建的几个dashboard简要记录下创建过程. 本次使用了grafana做可视化展示,data source使用的rds是postgresql和时序数据库in ...