[C#2] 5-迭代器

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代码得知]。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏每日一篇技术文章

Swift3.0 - 对象和类

1.对象中的所有变量或者常量在定义时如果不初始化,在对象初始化的时候,必须初始化,这个是swift安全性考虑,可选类型没有强制性要求初始化,因为系统默认给可选类...

1001
来自专栏柠檬先生

es6 数组扩展方法

1.扩展运算符     含义: 扩展运算符,三个点(...),将一个数组转为用逗号分隔的参数顺序。       例如:         console.log(...

2279
来自专栏分布式系统和大数据处理

C#中的枚举器(译)

翻译文章,原文链接(已失效):http://www.ondotnet.com/pub/a/dotnet/2004/06/07/liberty.html

1944
来自专栏racaljk

[golang] go的typeswitch guard(类型区别)语法和type assertion(类型断言)语法

最近在实现golang,看到个go的特性语法: typeswitch guard。

1543
来自专栏黑泽君的专栏

思想:java中,父类的方法中传入的形参的数据类型是泛型,子类的方法的形参想只要一种确定的数据类型,子类该如何做呢?

1952
来自专栏python3

python 集合

说明: 拿list_1每一个元素去list_2中查找,如果有,直接忽略,否则就直接输出。

1352
来自专栏博客园

.NET面试题解析(04)-类型、方法与继承

6. 在继承中new和override相同点和区别?看下面的代码,有一个基类A,B1和B2都继承自A,并且使用不同的方式改变了父类方法Print()的行为。测试...

1413
来自专栏程序员互动联盟

【编程基础】C语言类型转换

我们在编程序的时候,经常会出现不同类型的数据之间需要计算、赋值,必然会出现类型转换问题。C语言的变量数据类型是可以转换的,转换的方法有两类,一种是自动转换,一种...

44913
来自专栏技术博客

C#基础知识系列七(base、this、new、override、abstract、virtual、static)

本文主要来讲解一下C#中,自己觉得掌握的不怎么样或者用的不多,不太熟悉的关键字,主要包括base、this、new、override、abstract、virt...

822
来自专栏令仔很忙

浅谈C#中new、override、virtual关键字的区别

OO思想现在已经在软件开发项目中广泛应用,其中最重要的一个特性就是继承,最近偶简单的学习了下在设计模式中涉及到继承这个特性时,所需要用到的关键字,其中有一些关键...

1201

扫码关注云+社区

领取腾讯云代金券