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

 

  

posted @ 2012-08-27 11:36  金河  阅读(3292)  评论(0编辑  收藏  举报