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

  • 相关阅读:
    Transformers 简介(下)
    OpenCV-Python 姿态估计 | 五十
    Transformers 简介(上)
    OpenCV-Python 相机校准 | 四十九
    在Keras中可视化LSTM
    分析师和统计学家可以和谐相处吗?
    Array类模板
    C++中 公有继承 私有继承 和保护继承的区别
    文件输入输出
    PTA(浙大数据结构,c语言)
  • 原文地址:https://www.cnblogs.com/linianhui/p/csharp2_iterators.html
Copyright © 2020-2023  润新知