c# 迭代器

学习笔记:《深入理解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();
        }
    }
View Code

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;
            }
        }
    }
}

 

posted @ 2018-09-09 20:09  CodeMover92  阅读(354)  评论(0编辑  收藏  举报