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 类和对象 本文知识点:类和对象 说明:因为时间紧张,本人写博客过程中只是对知识点 ...
随机推荐
- JFreeChart插件使用
以java project为例,首先需要导入需要的jar包:jcommon-1.0.23.jar, jfreechart-1.0.19.jar. 画饼状图示例: package com.it.jfch ...
- <SDOI2009>学校食堂
我. 调了快一天 因为一个位置错误的感叹号 :-) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 狗dp #include<cstdio> #include<cstr ...
- JDK1.8新特性Lambda表达式
/** * Lambda * @date 2019/8/2 10:03 */ public class Lamda { public static void main(String[] args){ ...
- html解析过程
Web页面运行在各种各样的浏览器当中,浏览器载入.渲染页面的速度直接影响着用户体验 简单地说,页面渲染就是浏览器将html代码根据CSS定义的规则显示在浏览器窗口中的这个过程.先来大致了解一下浏览器都 ...
- Jmeter运行不显示cmd对话框
1.Jmeter运行不显示cmd对话框 如图所示,在Jmeter的bin目录下新建一个vbs的脚本,脚本内容为: Dim wsh Set wsh=WScript.CreateObject(" ...
- Nginx502,504和499错误解决方案
499错误解决方案 499错误是什么?让我们看看NGINX的源码中的定义: ngx_string(ngx_http_error_495_page), /* 495, https certificate ...
- Docker Swarm和Kubernetes在大规模集群中的性能比较
Contents 这篇文章主要针对Docker Swarm和Kubernetes在大规模部署的条件下的3个问题展开讨论.在大规模部署下,它们的性能如何?它们是否可以被批量操作?需要采取何种措施来支持他 ...
- 从5个经典工作开始看语义SLAM
本文试图概括Semantic SLAM的主要思路和近年工作,⻓期更新.但因水平有限,若有错漏,感谢指正. (更好的公式显示效果,可关注文章底部的公众号) Semantic SLAM 简介 至今为止,主 ...
- Java和C++引用的区别
Java的引用实际上是对指针的一个封装. C++的引用是变量的一个别名. Java的定义出来的变量(除了基本类型)其实就是一个引用,指向真正的对象. C++可以通过将引用传入函数,在函数内修改所引用的 ...
- 大厂常问iOS面试题--性能优化篇
1.造成tableView卡顿的原因有哪些? 1.最常用的就是cell的重用, 注册重用标识符 如果不重用cell时,每当一个cell显示到屏幕上时,就会重新创建一个新的cell 如果有很多数据的时候 ...