学习笔记:《深入理解C#》第六章:实现迭代器的捷径
1:C#1:手写迭代器的痛苦
迭代器的模式重要方面就是,不用一次返回所有数据,调用代码一次只需要获取一个元素。
迭代器的内部实现原理:
public class Person { public Person(string fName, string lName) { this.firstName = fName; this.lastName = lName; } public string firstName; public string lastName; } public class People : IEnumerable { private Person[] _people; public People(Person[] pArray) { _people = new Person[pArray.Length]; for (int i = 0; i < pArray.Length; i++) { _people[i] = pArray[i]; } } public IEnumerator GetEnumerator() { for (int i = 0; i < _people.Length; i++) { yield return _people[i]; } } } public class PeopleEnum : IEnumerator { public Person[] _people; int position = -1; public PeopleEnum(Person[] list) { _people = list; } public bool MoveNext() { position++; return (position < _people.Length); } public void Reset() { position = -1; } object IEnumerator.Current { get { return Current; } } public Person Current { get { try { return _people[position]; } catch (IndexOutOfRangeException) { throw new InvalidOperationException(); } } } } class Program { static void Main(string[] args) { Person[] peopleArray = new Person[3] { new Person("John", "Smith"), new Person("Jim", "Johnson"), new Person("Sue", "Rabon"), }; People peopleList = new People(peopleArray); foreach (Person p in peopleList) Console.WriteLine(p.firstName + " " + p.lastName); Console.ReadKey(); } }
2:c#2:利用yield语句简化迭代器
将Person类修改如下
public class People : IEnumerable { private Person[] _people; public People(Person[] pArray) { _people = new Person[pArray.Length]; for (int i = 0; i < pArray.Length; i++) { _people[i] = pArray[i]; } } public IEnumerator GetEnumerator() { for (int i = 0; i < _people.Length; i++) { yield return _people[i]; } } }
3:实例:利用IEnumerable<T>实现计算斐波那契数列
如果不想预先进行计算,并把结果缓存起来供后来使用那么下面方法是非常有用的,他会计算出一个斐波那契数列,数量有输入参数指定,延后把结果封装到IEnumerable中,以便foreach或以IEnumerable为输入的方法使用。
class Program { static void Main(string[] args) { foreach (long fib in FibonacciGenerator.GetSequence(100)) { Console.WriteLine(fib); } Console.ReadKey(); } } class FibonacciGenerator { public static IEnumerable<long> GetSequence(int count) { long fib1 = 0; long fib2 = 1; yield return fib1; yield return fib2; while (--count != 1) { long fib3 = fib1 + fib2; yield return fib3; fib1 = fib2; fib2 = fib3; } } } }