迭代器(iterator)有时又称光标(cursor),它是程序设计的软件设计模式。
迭代器模式提供一个方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的标识。在表现效果上看是可以在容器对象(例如链表或数组)上遍历访问的接口,设计人员无需关心容器对象的内存分配的实现细节。可以用foreach遍历的类,都是实现了迭代器。
简单来说,迭代器模式使得你能够获取到序列中的所有元素而不用关心是其类型是array,list,linked list或者是其他什么序列结构。这一点使得能够非常高效的构建数据处理通道(data pipeline)--即数据能够进入处理通道,进行一系列的变换,或者过滤,然后得到结果。事实上,这正是LINQ的核心模式。
举个例子,使用迭代器写个和foreach类似的功能来遍历一个字符串,输出它每个字符:
static void Main() { string str = "ABCDEFG"; foreachFunc(str); foreach (char a in str) { Console.WriteLine("官方foreach里的循环是:" + a); } } static void foreachFunc(string str) { IEnumerator e = str.GetEnumerator(); while (e.MoveNext()) { Console.WriteLine("民间foreach里的循环是:" + e.Current); } }
效果是:
foreach的本质是先获取in后面这个对象的IEnumerator(会调用对象其中的GetEnumerator方法来获取),然后执行得到这个IEnumerator对象中的MoveNext方法。其实只要MoveNext方法的返回值时true就会去得到current,然后复制给item。
举个例子:
forreach (int item in list) { Console.writeLine(item); }
yield return是c#提供给我们的语法糖。
所谓语法糖,也称糖衣语法。其主要作用就是将复杂逻辑简单化,可以增加程序的可读性,从而减少程序代码出错的机会。
关键接口:IEnumerable
命名空间:using System.collections;
让想要通过foreach遍历的自定义类实现接口中的方法GetEnumerator即可
举个例子:
class CustomList2 : IEnumerable { private int[] list; public CustomList2() { list = new int[] { 1,2,3,4,5,6,7,8}; } public IEnumerator GetEnumerator() { throw new NotImplementedException(); } }