[C#2] 5-迭代器

简介: 1.枚举数 枚举数是循环访问其关联集合的对象。它可被视作指向集合中任何元素的可移动的指针。 一个枚举数只能与一个集合关联,但一个集合可以具有多个枚举数。C#的foreach 语句使用枚举数并隐藏操作该枚举数的复杂性。

1.枚举数

枚举数是循环访问其关联集合的对象。它可被视作指向集合中任何元素的可移动的指针。 一个枚举数只能与一个集合关联,但一个集合可以具有多个枚举数。C#的foreach 语句使用枚举数并隐藏操作该枚举数的复杂性。枚举数可用于读取集合中的数据,但不能用于修改基础集合。

集合要支持foreach则需要实现System.Collections.IEnumerable接口[公开枚举数,该枚举数支持在非泛型集合上进行简单迭代, 也可以不实现该接口,该接口定义了一个方法GetEnumerator(),返回一个支持IEnumerator接口的对象,IEnumerator的成员如下:

名称 说明
bool MoveNex t方法 将枚举数推进到集合的下一个元素
void Rese t方法 将枚举数设置为其初始位置,该位置位于集合中第一个元素之前
object Current 属性 获取集合中的当前元素

写一个:

 1  
 2 public class MyCollections : IEnumerable
 3 {
 4     private string[] items;
 5     MyCollections(string[] items)
 6     {
 7         this.items = items;
 8     }
 9     public IEnumerator GetEnumerator()
10     {
11         return new MyEnumerator(this);
12     }
13     public class MyEnumerator : IEnumerator
14     {
15         private int position = -1;
16         private MyCollections mc;
17         public MyEnumerator(MyCollections mc)
18         {
19             this.mc = mc;
20         }
21         public bool MoveNext()
22         {
23             if (position < this.mc.items.Length - 1)
24             {
25                 position++;
26                 return true;
27             }
28             else
29             {
30                 return false;
31             }
32         }
33         public void Reset()
34         {
35             position = -1;
36         }
37         object IEnumerator.Current
38         {
39             get
40             {
41                 return this.mc.items[position];
42             }
43         }
44     }
45     static void Main()
46     {
47         MyCollections f = new MyCollections(
48                     new string[] { "乱舞春秋", "", "22" });
49         foreach (string item in f)
50         {
51             Console.WriteLine(item);
52         }
53     }
54 }

2.迭代器

C#2.0以前,要使自己的集合支持foreach遍历,需要写上面一大堆代码[实现两个接口,也可不实现, 但是必须给提供这两个接口中的同名方法],C#2.0引入了yield return[返回每个元素]和yield break[终止迭代]两个组合而成的上下文关键字。 改写上述代码:

//MyEnumerable方法全部删掉
public IEnumerator GetEnumerator()
{
    for (int i = 0; i < items.Length; i++)
    {
        yield return items[i];
    }
}

就是这么简单!只需实现一个接口IEnumerable就可以了[或者说有public IEnumerator GetEnumerator()此方法就可];

像是匿名方法一样,编译器帮我们做了很多[这里编译器帮我们生成了"实现IEnumerator接口的一个类",通过查看IL代码得知]。

作者: Blackheart
目录
相关文章
|
设计模式 开发框架 .NET
C#——迭代器
C#——迭代器
161 0
C#——迭代器
|
C# 图形学
【unity之c#】所以迭代器的原理知识你还清楚吗?
【unity之c#】所以迭代器的原理知识你还清楚吗?
286 0
C#编程-94:迭代器Iterator简单实例
C#编程-94:迭代器Iterator简单实例
199 0
C#编程-94:迭代器Iterator简单实例
C#编程-93:迭代器Iterator概述
C#编程-93:迭代器Iterator概述
148 0
C#编程-93:迭代器Iterator概述
C#编程-93:迭代器Iterator概述
C#编程-93:迭代器Iterator概述C
202 0
C#编程-93:迭代器Iterator概述
|
Java C# 设计模式
使用C# (.NET Core) 实现迭代器设计模式 (Iterator Pattern)
本文的概念来自深入浅出设计模式一书 项目需求 有两个饭店合并了, 它们各自有自己的菜单. 饭店合并之后要保留这两份菜单. 这两个菜单是这样的: 菜单项MenuItem的代码是这样的: 最初我们是这样设计的, 这是第一份菜单: 这是第2份菜单: 同时有两个菜单存在的问题 问题就是多个菜单把事情变复杂了.
1139 0
|
C#
编写高质量代码改善C#程序的157个建议[勿选List<T>做基类、迭代器是只读的、慎用集合可写属性]
原文:编写高质量代码改善C#程序的157个建议[勿选List做基类、迭代器是只读的、慎用集合可写属性] 前言   本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html 。
1095 0
|
C#
编写高质量代码改善C#程序的157个建议[勿选List<T>做基类、迭代器是只读的、慎用集合可写属性]
前言   本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html 。本文主要学习记录以下内容:   建议23、避免将List作为自定义集合类的基类    建议24、迭代器应该是只读的   建议25、谨慎集合属性的可写操作 建议23、避免将List作为自定义集合类的基类  如果要实现一个自定义的集合类,最好不要以List作为基类,而应该扩展相应的泛型接口,通常是Ienumerable和ICollection(或ICollection的子接口,如IList。
993 0