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 类和对象 本文知识点:类和对象 说明:因为时间紧张,本人写博客过程中只是对知识点 ...
随机推荐
- Thymeleaf模板笔记
1.常用标签: 使用thymeleaf模板,首要在html中引入: <html xmlns:th="http://www.thymeleaf.org"> 引入css.j ...
- Nginx笔记总结十九:nginx + fancy实现漂亮的索引目录
编译:./configure --prefix=/usr/local/nginx --add-module=../ngx-fancyindex-master 配置: location / { fanc ...
- Java实现Luhm算法--银行卡号合法性校验
银行卡是由"发卡行标识代码 + 自定义 + 校验码 "等部分组成的. 银联标准卡与以往发行的银行卡最直接的区别就是其卡号前6位数字的不同. 银行卡卡号的前6位是用来表示发卡银行 ...
- 18.09.22模拟赛T2 历史
网上基本上找不到这道题,何况LJJ还稍微改了一下...... 原题:传送门 题目描述 ljj 被S 国数不清的漂亮小姐姐所吸引,为了搞清楚为什么S 国有如此多的漂亮小姐姐,他决定研究S 国的历史. 根 ...
- 吴裕雄--天生自然 R语言开发学习:使用ggplot2进行高级绘图(续二)
#----------------------------------------------------------# # R in Action (2nd ed): Chapter 19 # # ...
- struts2和springmvc性能比较2
我们用struts2时采用的传统的配置文件的方式,并没有使用传说中的0配置.spring3 mvc可以认为已经100%零配置了(除了配置spring mvc-servlet.xml外). Spring ...
- 递归遍历磁盘下的某一文件夹中所有文件,并copy文件生成文件和带文件夹的文件
package com.hudong.test; import java.io.File; import java.io.IOException; import java.util.ArrayList ...
- Autotestplat.com 更新了!
1 提供测试发帖留言功能 2 自动化平台体验功能 3 提供招聘资讯功能 4 提供推荐书籍功能
- usb设备枚举过程
USB主机在检测到USB设备插入后,就要对设备进行枚举了.为什么要枚举呢?枚举就是从设备读取一些信息,知道设备是什么样的设备,如何进行通信,这样主机就可以根据这些信息来加载合适的驱动程序.调试USB设 ...
- iOS常用框架源码分析
SDWebImage NSCache 类似可变字典,线程安全,使用可变字典自定义实现缓存时需要考虑加锁和释放锁 在内存不足时NSCache会自动释放存储的对象,不需要手动干预 NSCache的key不 ...