两种可以在Foreach中遍历的集合类

下面的代码示例阐释如何编写可与 foreach 一起使用的非泛型集合类。 id=tgt2 class=tgtSentence xmlns="http://msdn2.microsoft.com/mtps" mtps:Sentence sentenceid="33e2dfb1785dccd7056b99ec7aeeb5fb" runat="server" msdn2.microsoft.com>该类是字符串标记化拆分器,类似于 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 

 

 

class=tgtSentence xmlns="http://msdn2.microsoft.com/mtps" mtps:Sentence sentenceid="7dfaabcf79807a9b355d313b7f5b47bd" runat="server" msdn2.microsoft.com> mtps:Sentence msdn2.microsoft.com>下现是调用这两个集合类的主函数:

 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 

 

 

转载于:https://www.cnblogs.com/macacoonline/archive/2010/12/26/Foreach.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值