zoukankan      html  css  js  c++  java
  • IEnumerable和IEnumerator的区别

        一直对IEnumerable和IEnumerator的感觉到非常迷惑,后来我突然从接口定义的角度来思考

    这两个东西,感觉迷惑减少很多,于是按照接口来分析一下。

        1,什么是接口?

    接口就是你定义一些方法或者属性,但是不实现,让继承你的类去实现。凡是继承接口的类必须实现接口。比如这两个接口的定义如下:

        public interface IEnumerable //(接口)枚举数定义
        {
            IEnumerator GetEnumerator();//只有一个方法,返回类型是IEnumerator
        }
        public interface IEnumerator//(接口)枚举器定义
        {
            Object Current { get; } //属性,返回类型Object
            bool MoveNext(); //读Current值之前,MoveNext将枚举数提前到集合的第一个元素。
            void Reset();//将枚举数被定位于集合中第一个元素的前面
        }

        2,分析接口

    如果你想使用枚举,就必须实现接口IEnumerable的方法GetEnumerator(),但是这个方法

    返回类型是IEnumerator,他才是真正的实现枚举的功臣,因此要枚举的容器就必须实现

    IEnumerator的方法和属性。

       这里面我们可以使用让容器a实现IEnumerable,这个容器a也是我们想要枚举的容器。

       使用容器b实现IEnumerator,当然容器a和b装的数据是相同的。

       容器a直接使用GetEnumerator()得到IEnumerator对象(容器b).

        3,下面通过例子来看一下,这个例子取自msdn,但是直接看例子不好懂,我将必要的东西提出来,如下:

    (1)People相当于容器a,PeopleEnum相当于容器b。

        public class Person  //一个人
        {       
        }
        public class People : IEnumerable   //人的容器,需要实现 IEnumerable接口的成员
        {
            IEnumerator IEnumerable.GetEnumerator()  //实现接口IEnumerable的唯一成员
            {
                return (IEnumerator)GetEnumerator(); //返回类型转为IEnumerator
            }
    
            public PeopleEnum GetEnumerator() //自定义方法
            {
                return new PeopleEnum(_people);
            }
        }
        public class PeopleEnum : IEnumerator  //IEnumerator的子类
        {       
            public PeopleEnum(Person[] list) //构造函数
            {          
            }
            public bool MoveNext() //IEnumerator的方法
            {           
            }
            public void Reset()  //IEnumerator的方法
            {           
            }
    
            object IEnumerator.Current //IEnumerator的属性
            {
                get
                {
                    return Current;
                }
            }
    
            public Person Current
            {           
            }
        }
    People 实现 IEnumerable 说明People是可以枚举的,但是怎么枚举呢?
    PeopleEnum 实现 IEnumerator ,真正的实现了枚举。他们通过GetEnumerator建立联系。
    (2)下面是这个完整的例子:
    View Code
    using System;
    using System.Collections;
    
    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];
            }
        }
    
        IEnumerator IEnumerable.GetEnumerator()
        {
           return (IEnumerator) GetEnumerator();
        }
    
        public PeopleEnum GetEnumerator()
        {
            return new PeopleEnum(_people);
        }
    }
    
    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);
    
        }
    }

    3,下面再给一个连接,也是解释这个的

    http://www.cnblogs.com/illele/archive/2008/04/21/1164696.html

     

      

  • 相关阅读:
    Redis5.x五种数据类型常见命令
    Redis5.x安装以及常见数据类型
    《Redis5.x入门教程》正式推出
    PPT制作套路指南
    如何更优雅地对接第三方API
    软件开发要质量还是要效率?
    前后端分离对于开发人员的挑战
    Spring中老生常谈的FactoryBean
    消费端如何保证消息队列MQ的有序消费
    《ElasticSearch6.x实战教程》之实战ELK日志分析系统、多数据源同步
  • 原文地址:https://www.cnblogs.com/wang7/p/2658276.html
Copyright © 2011-2022 走看看