Foreach遍历集合类原理

下面的代码示例阐释如何编写可与 foreach 一起使用的非泛型集合类。 该类是字符串标记化拆分器,类似于 C 运行时函数 strtok_s

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Collections;
 6 
 7 namespace Macaco.Study.ConsoleProject
 8 {
 9     /*
10      * 注意:数组下标在下文中称为“索引”或“索引位置”
11      */
12     public class Each_Inherit:IEnumerable
13     {
14         //创建用于存放字符串的数组
15         private string[] elements;
16 
17         /// <summary>
18         /// 赋值构造
19         /// </summary>
20         /// <param name="source">数据</param>
21         /// <param name="delimiters">分隔符</param>
22         public Each_Inherit(string source, char[] delimiters)
23         {
24             //将字符串按指定的分隔符分割到字符串数组中
25             elements = source.Split(delimiters);
26         }
27 
28         /// <summary>
29         /// 返回一个循环访问集合的枚举器。
30         /// </summary>
31         /// <returns>可用于循环访问集合的 System.Collections.IEnumerator 对象。</returns>
32         public IEnumerator GetEnumerator()
33         {
34             return new Each_InheritEnum(this);
35         }
36 
37         /// <summary>
38         /// 循环访问集合的枚举器类
39         /// </summary>
40         public class Each_InheritEnum:IEnumerator
41         {
42             //创建当前遍的索引位置
43             private int position = -1;
44 
45             //创建要在Foreach中遍历的对象
46             private Each_Inherit ea;
47 
48             /// <summary>
49             /// 赋值构造
50             /// </summary>
51             /// <param name="ea">要在Foreach中遍历的对象</param>
52             public Each_InheritEnum(Each_Inherit ea)
53             {
54                 this.ea = ea;
55             }
56 
57             /// <summary>
58             /// 返回当前索引所对应的对象
59             /// </summary>
60             public object Current
61             {
62                 get { return ea.elements[position]; }
63             }
64 
65             /// <summary>
66             /// 设置下一轮循环的索引位置
67             /// </summary>
68             /// <returns>返回是否继续下一轮循环</returns>
69             public bool MoveNext()
70             {
71                 if (position < ea.elements.Length - 1)
72                 {
73                     position++;
74                     return true;
75                 }
76                 else
77                 {
78                     return false;
79                 }
80             }
81 
82             /// <summary>
83             /// 重置当前索引位置
84             /// </summary>
85             public void Reset()
86             {
87                 position = -1;
88             }
89         }
90     }
91 }
92 

  在 C# 中,集合类不一定要从 IEnumerableIEnumerator 继承以便与 foreach 兼容。 只要此类具有必需的 GetEnumeratorMoveNextResetCurrent 成员,就可 foreach 与一起使用。 省略接口有一个好处:您可以将 Current 的返回类型定义得比 Object 更为明确,从而提供类型安全。

例如以下代码: 

 1  using  System;
 2  using  System.Collections.Generic;
 3  using  System.Linq;
 4  using  System.Text;
 5 
 6  namespace  Macaco.Study.ConsoleProject
 7  {
 8       public   class  Each_NOInherit
 9      {
10           public   string [] elements;
11 
12           public  Each_NOInherit( string  source, char [] delimiters)
13          {
14              elements  =  source.Split(delimiters);
15          }
16 
17           ///   <summary>
18           ///  返回一个循环访问集合的枚举器。
19           ///   </summary>
20           ///   <returns> 可用于循环访问集合的Each_NoInheritEnum对象。 </returns>
21           public  Each_NOInheritEnum GetEnumerator()
22          {
23               return   new  Each_NOInheritEnum( this );
24          }
25 
26           ///   <summary>
27           ///  循环访问集合的枚举器类
28           ///   </summary>
29           public   class  Each_NOInheritEnum
30          {
31               private   int  position =- 1 ;
32 
33               private  Each_NOInherit ea;
34 
35               public  Each_NOInheritEnum(Each_NOInherit ea)
36              {
37                   this .ea  =  ea;
38              }
39 
40               ///   <summary>
41               ///  返回当前索引所对应的字符串
42               ///   </summary>
43               public   string  Current
44              {
45                   get  {  return  ea.elements[position]; }
46              }
47 
48               public   bool  MoveNext()
49              {
50                   if  (position  <  ea.elements.Length  -   1 )
51                  {
52                      position ++ ;
53                       return   true ;
54                  }
55                   else  
56                  {
57                       return   false ;
58                  }
59              }
60 
61               public   void  Resset()
62              {
63                  position  =   - 1 ;
64              }
65          }
66      }
67  }
68 

 

 

下现是调用这两个集合类的主函数:

 1  using  System;
 2  using  System.Collections.Generic;
 3  using  System.Linq;
 4  using  System.Text;
 5 
 6  namespace  Macaco.Study.ConsoleProject
 7  {
 8       class  Program
 9      {
10           static   void  Main( string [] args)
11          {
12              Each_Test();
13          }
14           private   static   void  Each_Test()
15          {
16               // 该类继承自IEnumerable接口,实现接口方法GetEnumerator
17              Each_Inherit ea  =   new  Each_Inherit( " This is Each_Inherit Test " new   char [] {  '   ' ' _ '  });
18 
19              Console.WriteLine( " -------Inherit Result------- " );
20               foreach  ( string  str  in  ea)
21              {
22                  Console.WriteLine(str);
23              }
24              Console.WriteLine( " ---------------------------- " );
25 
26              Console.WriteLine();
27 
28               // 该类没有继承自IEnumerable,但是具有GetEnumerator方法
29              Each_NOInherit eaNo  =   new  Each_NOInherit( " This is Each_NO_Inherit Test " new   char [] {  '   ' ' _ '  });
30 
31              Console.WriteLine( " ------No Inherit Result----- " );
32               foreach  ( string  str  in  eaNo)
33              {
34                  Console.WriteLine(str);
35              }
36              Console.WriteLine( " ---------------------------- " );
37          }
38           /* OutPut:
39           * -------Inherit Result-------
40           *  This
41           *  is
42           *  Each
43           *  Inherit
44           *  Test
45           * ----------------------------
46           * 
47           * ------No Inherit Result-----
48           *  This
49           *  is
50           *  Each
51           *  NO
52           *  Inherit
53           *  Test
54           * ----------------------------
55            */
56 
57          /*  
58          *第一种:实现IEnumerable和IEnumerator接口
59          *第二种:不实现任何接口,但具备以上两个接口中需要实现的方法
60          *优缺点:
61          *  1.第一种集合类能够与其他公共语言运行时 兼容语言的 foreach 语句或等效项交互操作,而第二种不能。 
62          *  2.第一种集合类不可以将 Current 的返回类型定义得比 Object 更为明确,因此无法提供类型安全,
63          *    而第二种集合类可以将Current的返回定义为string从而能够提供更好的类型安全。
64           */
65      }
66  }
67 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值