• IEnumerable & IEnumerator


    IEnumerable 只有一个方法:IEnumerator GetEnumerator(). INumerable 是集合应该实现的一个接口,这样,就能用 foreach 来遍历这个集合。
    IEnumerator 有Current属性,MoveNext(), Reset()两个方法。
     
    当 foreach 使用到一个 IEnumerable 的集合上的时候,遍历是这样开始的:
    1. 调用 GetEnumerator() 得到一个 IEnumerator 的对象。
    2. 调用 MoveNext();
    3. 使用 其中一个对象。
    4. 重复2和3, 直到 MoveNext()返回 false(没有下一个啦).
     
    由此可见
    1. GetEnumerator() 返回的对象在最开始的时候,指针是放在第一个对象之前的,Reset()之后也是这样。
    2. 为了使用 foreach, 实现 IEnumerable 不是必须的,只是一个 best practice 而已。
     
    下面我们来看微软提供的一个例子: 
    using System;
    using System.Collections;
    
    // Simple business object.
    public class Person
    {
        public Person(string fName, string lName)
        {
            this.firstName = fName;
            this.lastName = lName;
        }
    
        public string firstName;
        public string lastName;
    }
    
    // Collection of Person objects. This class
    // implements IEnumerable so that it can be used
    // with ForEach syntax.
    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];
            }
        }
    
    // Implementation for the GetEnumerator method.
        IEnumerator IEnumerable.GetEnumerator()
        {
           return (IEnumerator) GetEnumerator();
        }
    
        public PeopleEnum GetEnumerator()
        {
            return new PeopleEnum(_people);
        }
    }
    
    // When you implement IEnumerable, you must also implement IEnumerator.
    public class PeopleEnum : IEnumerator
    {
        public Person[] _people;
    
        // Enumerators are positioned before the first element
        // until the first MoveNext() call.
        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 App
    {
        static void Main()
        {
            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);
    
        }
    }
    
    /* This code produces output similar to the following:
     *
     * John Smith
     * Jim Johnson
     * Sue Rabon
     *
     */
    

      

  • 相关阅读:
    Javascript 严格模式详解
    SeaJS与RequireJS最大的区别
    AMD 和 CMD 的区别有哪些?
    JS 关于(function( window, undefined ) {})(window)写法的理解
    高性能 CSS3 动画
    js对象私有变量公有变量问题
    探讨js字符串数组拼接的性能问题
    提高 DHTML 页面性能
    vue请求本地json数据
    vuejs绑定img 的src
  • 原文地址:https://www.cnblogs.com/ouyangdahai/p/7277854.html
Copyright © 2020-2023  润新知