[转]IEnumerator&IEnumerable集合

C# defines two interfaces to enumerate a collective object. Now let us see them:
public interface IEnumerator
{      
    object Current { get; }
    bool MoveNext();
    void Reset();
}
public interface IEnumerable
{
   IEnumerator GetEnumerator();
}
Now the question is: why does need the two interface? Maybe IEnumerator is enough. The Example is below::
class MyData : IEnumerator
{
   private int[] data;
   private int index;
      
   public MyData()
   {
       data = new int[10];
       index = -1;
    }
    public object Current
    {
        get { return data[index]; }
    }
    public bool MoveNext()
    {
        return ++index < data.Length;
    }
    public void  Reset()
    {
        index = -1;
    }
}

Is there any problem with this?
 Yes, there is. If you implement IEnumerator interface, not IEnumerable, there will be subtle problematic in some special cases. Now begin another example with MyData class object:
IEnumerator e = new MyData();
while (e.MoveNext())
{
  object o = e.Current;
  {
e.MoveNext();
    object o2 = e.Current;
    DoSomethingWith(o,o2);
   }
 }
 Do you see the potential problem above? This is caused by the essence of the IEnumberator interface. This interface force us to use the enumerator in this way:

 Set the original iterative position before the starting (Reset)
 Call MoveNext() function to move the position to the next, and check the current element is existing
 Get the current element from the Property Current
So , the IEnumberator is often implemented by using some internal state( in our MyData example it is the class instance member index). When you use the IEnumberator variable, you have to use it in the special way illuminated above. But when you use it in a nested way, you maybe destroy the object internal state, and the behavior is undefined.
 So, the .NET Framework provide another interface IEnumberable, which creates an IEnumerator variable by a function GetEnumberator(), and the internal state is saved in the variable returned. When you use it, you change the variable internal state, not the class instance variable implementing the interface IEnumerable, and the undefined behavior will never happen again.
 And remember, foreach is for IEnumerable, not for IEnumberator.



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=579173

posted @ 2007-02-26 14:30  馒头  阅读(748)  评论(0编辑  收藏  举报