zoukankan      html  css  js  c++  java
  • C#基础知识---迭代器与Foreach语句

    一、Foreach语句简介

    在C# 1.0中我们经常使用foreach来遍历一个集合中的元素,然而如果一个集合要支持使用foreach语句来进行遍历,这个集合一般需要IEnumerableIEnumerable<T>接口

    因为foreach是迭代语句,要使用foreach必须要有一个迭代器才行的,而IEnumerable接口中的IEnumerator GetEnumerator()方法是返回迭代器的。

    在C# 1.0中,要获得迭代器一般需要实现IEnumerable接口中的GetEnumerator()方法,然而要实现一个迭代器就必须实现IEnumerator接口。

    在C# 2.0中,提供 yield关键字来简化迭代器的实现。

    foreach被编译后会调用GetEnumerator来返回一个迭代器。

    二、C#1.0中实现迭代器

      1 using System;
      2 using System.Collections;
      3 
      4 namespace 迭代器Demo
      5 {
      6     class Program
      7     {
      8         static void Main(string[] args)
      9         {
     10             Friends friendcollection = new Friends();
     11             foreach (Friend f in friendcollection)
     12             {
     13                 Console.WriteLine(f.Name);
     14             }
     15 
     16             Console.Read();
     17         }
     18     }
     19 
     20     /// <summary>
     21     ///  朋友类
     22     /// </summary>
     23     public class Friend
     24     {
     25         private string name;
     26         public string Name
     27         {
     28             get { return name; }
     29             set { name = value; }
     30         }
     31         public Friend(string name)
     32         {
     33             this.name = name;
     34         }
     35     }
     36 
     37     /// <summary>
     38     ///   朋友集合
     39     /// </summary>
     40     public class Friends : IEnumerable
     41     {
     42         private Friend[] friendarray;
     43 
     44         public Friends()
     45         {
     46             friendarray = new Friend[]
     47             {
     48                 new Friend("张三"),
     49                 new Friend("李四"),
     50                 new Friend("王五")
     51             };
     52         }
     53 
     54         // 索引器
     55         public Friend this[int index]
     56         {
     57             get { return friendarray[index]; }
     58         }
     59 
     60         public int Count
     61         {
     62             get { return friendarray.Length; }
     63         }
     64 
     65         // 实现IEnumerable<T>接口方法
     66        public  IEnumerator GetEnumerator()
     67         {
     68             return new FriendIterator(this);
     69         }
     70     }
     71 
     72     /// <summary>
     73     ///  自定义迭代器,必须实现 IEnumerator接口
     74     /// </summary>
     75     public class FriendIterator : IEnumerator
     76     {
     77         private readonly Friends friends;
     78         private int index;
     79         private Friend current;
     80         internal FriendIterator(Friends friendcollection)
     81         {
     82             this.friends = friendcollection;
     83             index = 0;
     84         }
     85 
     86         #region 实现IEnumerator接口中的方法
     87         public object Current
     88         {
     89             get
     90             {
     91                 return this.current;
     92             }
     93         }
     94 
     95         public bool MoveNext()
     96         {
     97             if (index + 1 > friends.Count)
     98             {
     99                 return false;
    100             }
    101             else
    102             {
    103                 this.current = friends[index];
    104                 index++;
    105                 return true;
    106             }
    107         }
    108 
    109         public void Reset()
    110         {
    111             index = 0;
    112         }
    113 
    114         #endregion 
    115     }
    116 }
    View Code

    三、C#2.0中实现迭代器

     1 namespace 简化迭代器的实现
     2 {
     3     class Program
     4     {
     5         static void Main(string[] args)
     6         {
     7             Friends friendcollection = new Friends();
     8             foreach (Friend f in friendcollection)
     9             {
    10                 Console.WriteLine(f.Name);
    11             }
    12 
    13             Console.Read();
    14         }
    15     }
    16 
    17     /// <summary>
    18     ///  朋友类
    19     /// </summary>
    20     public class Friend
    21     {
    22         private string name;
    23         public string Name
    24         {
    25             get { return name; }
    26             set { name = value; }
    27         }
    28         public Friend(string name)
    29         {
    30             this.name = name;
    31         }
    32     }
    33 
    34     /// <summary>
    35     ///   朋友集合
    36     /// </summary>
    37     public class Friends : IEnumerable
    38     {
    39         private Friend[] friendarray;
    40 
    41         public Friends()
    42         {
    43             friendarray = new Friend[]
    44             {
    45                 new Friend("张三"),
    46                 new Friend("李四"),
    47                 new Friend("王五")
    48             };
    49         }
    50 
    51         // 索引器
    52         public Friend this[int index]
    53         {
    54             get { return friendarray[index]; }
    55         }
    56 
    57         public int Count
    58         {
    59             get { return friendarray.Length; }
    60         }
    61 
    62         // C# 2.0中简化迭代器的实现
    63         public IEnumerator GetEnumerator()
    64         {
    65             for (int index = 0; index < friendarray.Length; index++)
    66             {
    67                 // 这样就不需要额外定义一个FriendIterator迭代器来实现IEnumerator
    68                 // 在C# 2.0中只需要使用下面语句就可以实现一个迭代器
    69                 yield return friendarray[index];
    70             }
    71         }
    72     }
    73 }
    View Code

    在上面代码中有一个yield return 语句,这个语句的作用就是告诉编译器GetEnumerator方法不是一个普通的方法,而是实现一个迭代器的方法。

    当编译器看到yield return语句时,编译器知道需要实现一个迭代器,所以编译器生成中间代码时为我们生成了一个实现IEnumerator接口的内部类。

    大家可以通过Reflector工具进行查看,下面是通过Reflector工具得到一张截图:

    四、迭代器执行过程

    注:本文参考http://www.cnblogs.com/zhili/archive/2012/12/02/Interator.html

  • 相关阅读:
    洛谷 P1508 Likecloud-吃、吃、吃
    Codevs 1158 尼克的任务
    2017.10.6 国庆清北 D6T2 同余方程组
    2017.10.6 国庆清北 D6T1 排序
    2017.10.3 国庆清北 D3T3 解迷游戏
    2017.10.3 国庆清北 D3T2 公交车
    2017.10.3 国庆清北 D3T1 括号序列
    2017.10.4 国庆清北 D4T1 财富
    2017.10.7 国庆清北 D7T2 第k大区间
    2017.10.7 国庆清北 D7T1 计数
  • 原文地址:https://www.cnblogs.com/3xiaolonglong/p/9608281.html
Copyright © 2011-2022 走看看