·天新网首页·加入收藏·设为首页·网站导航
数码笔记本手机摄像机相机MP3MP4GPS
硬件台式机网络服务器主板CPU硬盘显卡
办公投影打印传真
家电电视影院空调
游戏网游单机动漫
汽车新车购车试驾
下载驱动源码
学院开发设计
考试公务员高考考研
业界互联网通信探索
您现在的位置:天新网 > 软件开发 > .Net开发 > C#
[C#基础知识系列]专题十一:迭代器
http://www.21tx.com 2012年12月04日

1 2 下一页

C# 1.0中我们经常使用foreach来遍历一个集合中的元素,然而一个类型要能够使用foreach关键字来对其进行遍历必须实现IEnumerable或IEnumerable<T>接口,(之所以来必须要实现IEnumerable这个接口,是因为foreach是迭代语句,要使用foreach必须要有一个迭代器才行的,然而IEnumerable接口中就有IEnumerator GetEnumerator()方法是返回迭代器的,所以实现了IEnumerable接口,就必须实现GetEnumerator()这个方法来返回迭代器,有了迭代器就自然就可以使用foreach语句了),然而在C# 1.0中要获得迭代器就必须实现IEnumerable接口中的GetEnumerator()方法,然而要实现一个迭代器就必须实现IEnumerator接口中的bool MoveNext()和void Reset()方法,然而 C# 2.0中提供 yield关键字来简化迭代器的实现,这样在C# 2.0中如果我们要自定义一个迭代器就容易多了。下面就具体介绍了C# 2.0 中如何提供对迭代器的支持.

一、迭代器的介绍

  迭代器大家可以想象成数据库的游标,即一个集合中的某个位置,C# 1.0中使用foreach语句实现了访问迭代器的内置支持,使用foreach使我们遍历集合更加容易(比使用for语句更加方便,并且也更加容易理解),foreach被编译后会调用GetEnumerator来返回一个迭代器,也就是一个集合中的初始位置(foreach其实也相当于是一个语法糖,把复杂的生成代码工作交给编译器去执行)。

二、C#1.0如何实现迭代器

  在C# 1.0 中实现一个迭代器必须实现IEnumerator接口,下面代码演示了传统方式来实现一个自定义的迭代器:

using System;   
 using System.Collections;   
        
 namespace 迭代器Demo   
 {   
     class Program   
     {   
         static void Main(string[] args)   
         {   
             Friends friendcollection = new Friends();   
             foreach (Friend f in friendcollection)   
             {   
                 Console.WriteLine(f.Name);   
             }   
        
             Console.Read();   
         }   
     }   
        
     /// <summary>   
     ///  朋友类   
     /// </summary>   
     public class Friend   
     {   
         private string name;   
         public string Name   
         {   
             get { return name; }   
             set { name = value; }   
         }   
         public Friend(string name)   
         {   
             this.name = name;   
         }   
     }   
        
     /// <summary>   
     ///   朋友集合   
     /// </summary>   
     public class Friends : IEnumerable   
     {   
         private Friend[] friendarray;   
        
         public Friends()   
         {   
             friendarray = new Friend[]   
             {   
                 new Friend("张三"),   
                 new Friend("李四"),   
                 new Friend("王五")   
             };   
         }   
        
         // 索引器   
         public Friend this[int index]   
         {   
             get { return friendarray[index]; }   
         }   
        
         public int Count   
         {   
             get { return friendarray.Length; }   
         }   
        
         // 实现IEnumerable<T>接口方法   
        public  IEnumerator GetEnumerator()   
         {   
             return new FriendIterator(this);   
         }   
     }   
        
     /// <summary>   
     ///  自定义迭代器,必须实现 IEnumerator接口   
     /// </summary>   
     public class FriendIterator : IEnumerator   
     {   
         private readonly Friends friends;   
         private int index;   
         private Friend current;   
         internal FriendIterator(Friends friendcollection)   
         {   
             this.friends = friendcollection;   
             index = 0;   
         }   
        
         #region 实现IEnumerator接口中的方法   
         public object Current   
         {   
             get
             {   
                 return this.current;   
             }   
         }   
        
         public bool MoveNext()   
         {   
             if (index + 1 > friends.Count)   
             {   
                 return false;   
             }   
             else
             {   
                 this.current = friends[index];   
                 index++;   
                 return true;   
             }   
         }   
        
         public void Reset()   
         {   
             index = 0;   
         }   
        
         #endregion    
     }   
 }

运行结果(上面代码中都有详细的注释,这里就不说明了,直接上结果截图):

[C#基础知识系列]专题十一:迭代器

三、使用C#2.0的新特性简化迭代器的实现

  在C# 1.0 中要实现一个迭代器必须实现IEnumerator接口,这样就必须实现IEnumerator接口中的MoveNext、Reset方法和Current属性,从上面代码中看出,为了实现FriendIterator迭代器需要写40行代码,然而在C# 2.0 中通过yield return语句简化了迭代器的实现,下面看看C# 2.0中简化迭代器的代码:

namespace 简化迭代器的实现   
 {   
     class Program   
     {   
         static void Main(string[] args)   
         {   
             Friends friendcollection = new Friends();   
             foreach (Friend f in friendcollection)   
             {   
                 Console.WriteLine(f.Name);   
             }   
        
             Console.Read();   
         }   
     }   
        
     /// <summary>   
     ///  朋友类   
     /// </summary>   
     public class Friend   
     {   
         private string name;   
         public string Name   
         {   
             get { return name; }   
             set { name = value; }   
         }   
         public Friend(string name)   
         {   
             this.name = name;   
         }   
     }   
        
     /// <summary>   
     ///   朋友集合   
     /// </summary>   
     public class Friends : IEnumerable   
     {   
         private Friend[] friendarray;   
        
         public Friends()   
         {   
             friendarray = new Friend[]   
             {   
                 new Friend("张三"),   
                 new Friend("李四"),   
                 new Friend("王五")   
             };   
         }   
        
         // 索引器   
         public Friend this[int index]   
         {   
             get { return friendarray[index]; }   
         }   
        
         public int Count   
         {   
             get { return friendarray.Length; }   
         }   
        
         // C# 2.0中简化迭代器的实现   
         public IEnumerator GetEnumerator()   
         {   
             for (int index = 0; index < friendarray.Length; index++)   
             {   
                 // 这样就不需要额外定义一个FriendIterator迭代器来实现IEnumerator   
                 // 在C# 2.0中只需要使用下面语句就可以实现一个迭代器   
                 yield return friendarray[index];   
             }   
         }   
     }   
 }

在上面代码中有一个yield return 语句,这个语句的作用就是告诉编译器GetEnumerator方法不是一个普通的方法,而是实现一个迭代器的方法,当编译器看到yield return语句时,编译器知道需要实现一个迭代器,所以编译器生成中间代码时为我们生成了一个IEnumerator接口的对象,大家可以通过Reflector工具进行查看,下面是通过Reflector工具得到一张截图:

上一篇: C#委托基础9——Invoke与委托
下一篇: C#委托基础8——lambda表达式

1 2 下一页

关于我们 | 联系我们 | 加入我们 | 广告服务 | 投诉意见 | 网站导航
Copyright © 2000-2011 21tx.com, All Rights Reserved.
晨新科技 版权所有 Created by TXSite.net