学习笔记:《深入理解C#》第六章:实现迭代器的捷径

1:C#1:手写迭代器的痛苦

迭代器的模式重要方面就是,不用一次返回所有数据,调用代码一次只需要获取一个元素。

迭代器的内部实现原理:

public class Person
{
public Person(string fName, string lName)
{
this.firstName = fName;
this.lastName = lName;
} public string firstName;
public string lastName;
} public class People : IEnumerable
{
private Person[] _people;
public People(Person[] pArray)
{
_people = new Person[pArray.Length]; for (int i = ; i < pArray.Length; i++)
{
_people[i] = pArray[i];
}
} public IEnumerator GetEnumerator()
{
for (int i = ; i < _people.Length; i++)
{
yield return _people[i];
}
}
} public class PeopleEnum : IEnumerator
{
public Person[] _people; int position = -; public PeopleEnum(Person[] list)
{
_people = list;
} public bool MoveNext()
{
position++;
return (position < _people.Length);
} public void Reset()
{
position = -;
} object IEnumerator.Current
{
get
{
return Current;
}
} public Person Current
{
get
{
try
{
return _people[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
}
class Program
{
static void Main(string[] args)
{
Person[] peopleArray = new Person[]
{
new Person("John", "Smith"),
new Person("Jim", "Johnson"),
new Person("Sue", "Rabon"),
}; People peopleList = new People(peopleArray); foreach (Person p in peopleList)
Console.WriteLine(p.firstName + " " + p.lastName); Console.ReadKey();
}
}

2:c#2:利用yield语句简化迭代器

将Person类修改如下

public class People : IEnumerable
{
private Person[] _people;
public People(Person[] pArray)
{
_people = new Person[pArray.Length]; for (int i = ; i < pArray.Length; i++)
{
_people[i] = pArray[i];
}
} public IEnumerator GetEnumerator()
{
for (int i = ; i < _people.Length; i++)
{
yield return _people[i];
}
}
}

3:实例:利用IEnumerable<T>实现计算斐波那契数列

如果不想预先进行计算,并把结果缓存起来供后来使用那么下面方法是非常有用的,他会计算出一个斐波那契数列,数量有输入参数指定,延后把结果封装到IEnumerable中,以便foreach或以IEnumerable为输入的方法使用。

class Program
{
static void Main(string[] args)
{
foreach (long fib in FibonacciGenerator.GetSequence())
{
Console.WriteLine(fib);
} Console.ReadKey();
}
} class FibonacciGenerator
{
public static IEnumerable<long> GetSequence(int count)
{
long fib1 = ;
long fib2 = ;
yield return fib1;
yield return fib2; while (--count != )
{
long fib3 = fib1 + fib2;
yield return fib3;
fib1 = fib2;
fib2 = fib3;
}
}
}
}

c# IEnumerable和IEnumerator枚举器的更多相关文章

  1. C# ~ 从 IEnumerable / IEnumerator 到 IEnumerable<T> / IEnumerator<T> 到 yield

    IEnumerable / IEnumerator 首先,IEnumerable / IEnumerator 接口定义如下: public interface IEnumerable /// 可枚举接 ...

  2. C#图解教程 第十八章 枚举器和迭代器

    枚举器和迭代器 枚举器和可枚举类型 foreach语句 IEnumerator接口 使用IEnumerable和IEnumerator的示例 泛型枚举接口迭代器 迭代器块使用迭代器来创建枚举器使用迭代 ...

  3. C# 枚举器和迭代器

    一.枚举器(enumerator)和可枚举类型(enumeration) 我们都知道foreach语句可以用来遍历数组中的元素,但你有没有想过为什么它可以被foreach处理呢? 这是因为数组可以按需 ...

  4. C# 枚举器(enumerator)

    总结: 1.枚举器就像是序列中的"游标"或"书签".可以有多个"书签",移动其中任何一个都可以枚举集合,与其他枚举器互不影响.用来遍历数据结 ...

  5. 关于IEnumerator<T>泛型枚举器 和 IEnumerable<T>

    在开发中我们经常会用到 IEnumerable<T> xxx 或者 List<T> xxx 这种集合或者集合接口,实际上就是一个线性表嘛然后结合C#提供的语法糖 foreach ...

  6. 【Unity|C#】基础篇(20)——枚举器与迭代器(IEnumerable/IEnumerator)

    [学习资料] <C#图解教程>(第18章):https://www.cnblogs.com/moonache/p/7687551.html 电子书下载:https://pan.baidu. ...

  7. C#枚举器接口IEnumerator的实现

    原文(http://blog.csdn.net/phpxin123/article/details/7897226) 在C#中,如果一个类要使用foreach结构来实现迭代,就必须实现IEnumera ...

  8. C#中的foreach语句与枚举器接口(IEnumerator)及其泛型 相关问题

    这个问题从<C#高级编程>数组一节中的foreach语句(6.7.2)发现的. 因为示例代码与之前的章节连贯,所以我修改了一下,把自定义类型改为了int int[] bs = { 2, 3 ...

  9. 【C#】构建可枚举类型(IEnumerable和IEnumerator)

    为了开始对实现既有接口的了解,我们就看一下IEnumerable和IEnumerator的作用,想一下,C#支持关键字foreach,允许我们遍历任何数组类型的内容: //遍历数组的项 ,,} for ...

随机推荐

  1. linux 使用进程管理工具 supervisor

    1.supervisor是使用python进行开发的运行在linux服务器上的进程管理工具 老版本的supervisor需要运行在python2环境,如果需要使用supervisor管理python3 ...

  2. Android实战源码--围住神经猫

    最终效果: AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manif ...

  3. Swift5 语言参考(九) 泛型和参数

    本章介绍泛型类型,函数和初始值设定项的参数和参数.声明泛型类型,函数,下标或初始化程序时,可以指定泛型类型,函数或初始化程序可以使用的类型参数.当创建泛型类型的实例或调用泛型函数或初始化程序时,这些类 ...

  4. @transactional作用和事务

    今天在博客园看到有发布spring的注解,留意到@transactional这个注解.立马就百度.学习了 使用这个注解的类或者方法表示该类里面的所有方法或者这个方法的事务由spring处理,来保证事务 ...

  5. node.js中的回调

    同步和阻塞:这两个术语可以互换使用,指的是代码的执行会在函数返回之前停止.如果某个操作阻塞,那么脚本就无法继续,这意味着必须等待. 异步和非阻塞:这两个术语可以互换使用,指的是基于回调的.允许脚本并行 ...

  6. odoo第三方市场 -- 模块推荐

    odoo 除了开源,另一个非常给力的地方就是,强大的第三方应用市场: 你入坑后,会发现非常的好玩,全球还有这么多小伙伴并肩前行,共同成长. 第三方市场有很多不错的模块,当然,好东西,不是完全免费的! ...

  7. 前端基础——css

    前端基础——css css的内容主要包括:盒子模型.定位.单位与取值.属性.选择器.

  8. vue通过webpack打包后怎么运行

    1. 成功使用webpack打包完成后会默认得到dist的文件夹 2. dist文件夹中有html与其他的静态文件 3. 在dist文件夹中打开命令窗口或者git,开一个服务器(像anywhere) ...

  9. Mybatis 事务管理和缓存机制

    一级缓存--SqlSession级别 数据库表tb_user User package com.example.demo.domain; public class User { private Int ...

  10. charles重复发包工具/repeat

    重复发包工具/repeat Charles 让你选择一个请求并重复,在测试后端接口的时候非常有用: Charles将请求重新发送到服务器,并将响应显示为新请求. 如果您进行后端更改并希望测试它们,用了 ...