C#2.0 迭代器
迭代器
迭代器模式是和为模式的一种范例,我们访问数据序列中所有的元素,不用关心序列是什么类型。从数据管道中数据经过一系列不同的转换或过滤后从管道的另一端出来。
像数组、集合等已经内置了迭代器,我们可以直接进行foreach,而我们自定义的类型,自然是无法进行这个操作的,对于自定义的类型实现迭代器模式通过IEnumerable和IEnumerator接口(或泛型接口)进行实现。在C#1.0中我们自定义类型实现迭代器是非常繁琐的
自定义迭代器
想要对IterationSample进行foreach,首先继承IEnumerable接口,会有一个GetEnumerator的方法需要去实现,这时创建另一个类实现IEnumerator接口,实现MoveNext方法与Current属性,我们需要进行位置的处理


这时就可以使用foreach这个"语法糖"进行遍历了,为什么说是语法糖呢, 因为这只是微软进行的一个封装处理,编译成IL过后还是会看到调用了GetEnumerator、MoveNext以及Current


这里在C#2.0中变的简单了,这时使用yield return就可以代替整个IterationSampleIterator这个类。

Yield return会告訴编译器这不是一个普通方法,而是实现迭代器块的方法。
这时可能会有疑問,都yield return了是不是代表方法结束了,并不是这样的,yield return 不代表方法執行结束 ,而是会在这里暫时退出。Yield return内部会为我们生成一个状态机,去维护MoveNext方法与Current属性
这时也许想要看看IL会生成什么样的代码呢,
可以看到有state(状态)current(当前属性)index(索引),用来记录块中位置以及局部变量的值 ,其实看起来和IterationSampleIterator类似,只不过帮我们去做了这个事

可能会对暂时退出产生疑问
下面写一个这样的例子帮助理解,在yield return前与后都有相应的输入,for循环三次,在方法最后打印方法结束

下面进行调用

可以看到以下输入,可以看到第一次执行MoveNext方法才会运行CreateEnumerable方法,也就是foreach是懶惰的,可以看到yield return方法就暂时退出了,只输出了yield return 前,下一次movenext会从上次的位置继续执行输出yield return后,循环结束后才会输出方法结束

除了yield return,还有yield break,这才是真正的直接退出相当与普通方法的return
使用自定义迭代器,可以简化对类型的遍历,有时我们需要读取文件中的第每一行,这样的代码经常会用到 。实现迭代器模型可以更加简化代码。
C#2.0 迭代器的更多相关文章
- Python学习笔记:06魔法方法和迭代器
魔法方法,属性和迭代器 新式类 通过赋值语句__metaclass=true或者class NewStyle(object)继承内建类object,可以表明是新式类. 构造方法 对象被创建后,会立即调 ...
- c# 迭代器 与 集合 IEnumerable.GetEnumerator 方法
示例来源 :msdn 参考:https://msdn.microsoft.com/zh-cn/library/dscyy5s0(v=vs.110).aspx 使用匿名方法.迭代器和部分选件类创建简洁的 ...
- 设计模式之迭代器模式(Iterator)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 带你深入理解STL之迭代器和Traits技法
在开始讲迭代器之前,先列举几个例子,由浅入深的来理解一下为什么要设计迭代器. //对于int类的求和函数 int sum(int *a , int n) { int sum = 0 ; for (in ...
- 迭代器和增强型for循环
★迭代器: Java集合框架的集合类,我们有时候称之为容器.容器的种类有很多种,比如ArrayList.LinkedList.HashSet...,每种容器都有自己的特点,ArrayList底层维护的 ...
- 类中的迭代器__iter__
什么是迭代器 有iter()函数返回,可以通过next(it)函数取值的对象就是迭代器 迭代器协议 迭代器协议是指对象能够使用next函数获取下一项数据,在没有下一项数据时触发一个StopIterat ...
- day18_文件处理_迭代器_生成器
#!/usr/bin/env python # -*- coding:utf-8 -*- # ********************day18_文件处理_迭代器_生成器 ************** ...
- Python里的迭代器
迭代器(iterator)协议 · 在Python中,支持迭代器协议就是实现对象的__iter__()和__next__()方法. 1.__iter__()方法:返回迭代器对象本身: 2.__next ...
- Collection迭代器Iterator的使用
package com.cx.Collecion; import java.util.ArrayList; import java.util.Collection; import java.util. ...
随机推荐
- 2016-3-1 Mac下使用Hexo搭建Blog
一.前期准备: 1.安装Node(必须):前往Node.js官网:https://nodejs.org/en/download/下载最新版本pkg软件,点击安装即可. 2.安装Git(必须):安装 ...
- 锐捷交换机配置DHCP SERVER给固定的MAC地址分配静态IP
今天突发奇想,想给自己的手机分配固定地址,使得接入公司无线网络时每次都取到同一ip地址,这样可以排除认证登录问题. 上网溜达一下,记录下锐捷官方的[常见问题]如下,经验证可行. 需求: 给MAC地址为 ...
- Vue 入门. 如何在HTML代码里面快速使用Vue
概述 browserify是一个 CommonJS风格的模块管理和打包工具,上一篇我们简单地介绍了Vue.js官方基于browserify构筑的一套开发模板.webpack提供了和browserify ...
- 我用linux系统的采坑记
我的新Ubuntu18,也没安装什么,但是在使用过程中总是莫名其妙的卡死,真的很烦.有时候cpu使用率接近100%,有时候貌似是内存不够了,但是我明明是8GB,这些小问题搞得我很恼火.这样的机器真的不 ...
- 32、可以拿来用的JavaScript实用功能代码
可以拿来用的JavaScript实用功能代码(可能会有些bug,用时稍微修改下,我用了几个还可以) 转载自 1.原生JavaScript实现字符串长度截取 function cutstr(str, l ...
- layui layer弹框中表格的显示
场景描述:点击iframe里面的一个按钮,需要在父级弹出一个弹框表格. 问题描述:这个弹框的分页不能正常显示,如果把layer.open前面的parent去掉,就可以正常显示. 代码展示: paren ...
- 封装一个 员工类 使用preparedStatement 查询数据 (1)
创建员工类 自动生成get set 方法 package cn.hph; public class emp { //定义表中的属性 private int id; private String en ...
- 【常用指令】git+服务器+数据库
git日程操作 服务器常用操作 ①同步master git pull origin master ②创建分支 git checkout -b 分支名 ③常规操作 git diff git add 文件 ...
- Docker常用命令(一)
[转]原始出处:http://zxx287856774.blog.51cto.com/3417296/1665264 docker中 启动所有的容器命令 docker start $(docker p ...
- Hash及HashMap简介
Hash简介: Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映射 ...