关闭

迭代器

329人阅读 评论(0) 收藏 举报
迭代器是使用在foreach中的集合。以前写过一篇《小议foreach》。在其中写了实现一个可以用于foreach的集合。在C#2.0中使用迭代器创建一个用于foreach的集合,实现上比较简单:继承于IEumnerable,并实现GetEnumerator()。
首先这个集合要基于IEnumerable(可以使用泛型),下面先来实现一个非泛型版的迭代器。代码如下(非泛型代码示例来源于MSDN):
public class DaysOfTheWeek : System.Collections.IEnumerable
        {
            string[] m_Days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" };
 
            public System.Collections.IEnumerator GetEnumerator()
            {
                for (int i = 0; i < m_Days.Length; i++)
                {
                    yield return m_Days[i];
                }
            }
        }
 
        class TestDaysOfTheWeek
        {
            static void Main()
            {
                DaysOfTheWeek week = new DaysOfTheWeek();
                foreach (string day in week)
                {
                    System.Console.Write(day + " ");
                }
                Console.Read();
            }
      }
操作结果是:
Sun Mon Tue Wed Thr Fri Sat
其中yied return关键字产生枚举元素
 
泛型版迭代器的实现代码如下:
static void Main(string[] args)
        {          
            Stack<int> stack = new Stack<int>();
            stack.items = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            foreach (int i in stack)
            {
                Console.WriteLine(i);
            }
            Console.Read();
     }
public class Stack<T> : IEnumerable<T>
    {
        public T[] items;
 
        public IEnumerator<T> GetEnumerator()
        {
            for (int i = 0; i < items.Length; i++)
            {
                yield return items[i];
            }
        }
 
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
}
运行结果如下:
1
2
3
4
5
6
7
8
9
10
其中G
在实现泛型迭代器时我一直没有写IEnumerator IEnumerable.GetEnumerator()这个方法,所以编译器一直在给我报错,(猜想)这个方法应该IEnumerator<T>接口中的一个抽象方法。而这个方法中调用的GetEnumerator(),通过集成环境中的提示发现,实际上是上面写到的IEnumerator<T> GetEnumerator()这个泛型方法。
 
在自定义迭代器时,我们可以利用yield break关键字跳出循环。如上面的例子中,我们想只输出小于等于5的项,调整上面代码,如:
public class Stack<T> : IEnumerable<T>
    {
        public T[] items;
 
        public IEnumerator<T> GetEnumerator()
        {
            for (int i = 0; i < items.Length; i++)
            {               
                if ((Convert.ToInt32(items[i]) > 5))
                    yield break;
                yield return items[i];
            }
        }
 
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
操作结果:
1
2
3
4
5
 
迭代器的机制:
    实际上迭代器只是在C#2.0中通过编译器一层额外处理的,用来简化创建可用于foreach的枚举集合的工作,从性能上没有什么变化。对于其生成的中间语言没有太多的变化。
 
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:108546次
    • 积分:2000
    • 等级:
    • 排名:第19308名
    • 原创:68篇
    • 转载:76篇
    • 译文:0篇
    • 评论:2条
    文章分类
    文章存档
    最新评论