IEnumerable和IEnumerator的使用

我对这两个接口的看法:
  1. 如果要实现foreach的调用,就必须实现这两个接口。
  2. IEnumerable接口:实现了这个接口的类可以使用foreach,实现的方法要返回的是一个对象(该对象是要遍历的对象,可以返回自身,也可以返回新的对象)。
  3. IEnumerator接口实现的方法是如何操作IEnumerable返回的对象(即:IEnumerable返回的对象必须实现IEnumerator这个接口)
  4. 两个接口,离开了任何一个,都不能单独运行
  5. 为什么这一套东西要分开?根据2和3,可以为一个类专门写一个foreach的类,这样使原类更简洁。
我复制粘贴了MSDN的例子:


    /// <summary>
    
/// 这个是一个人的类,有姓和名两个字段
    
/// </summary>
    public class Person
    {
        
public Person(string fName, string lName)
        {
            
this.firstName = fName;
            
this.lastName = lName;
        }

        
public string firstName;
        
public string lastName;
    }
    
/// <summary>
    
/// 这个是个集合类,实现了IEnumerable,
    
/// 表明People可以被foreach遍历
    
/// </summary>
    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];
            }
        }
        
/// <summary>
        
/// 接口的实现,返回的是一个PeopleEnum的一个类对象
        
/// </summary>
        
/// <returns></returns>
        public IEnumerator GetEnumerator()
        {
            
return new PeopleEnum(_people);
        }
    }
    
/// <summary>
    
/// 专门实现遍历的类,必须实现IEnumerator接口
    
/// 这样才能正常的进行数据遍历
    
/// </summary>
    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;
        }

        
public object 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);

    }
}

网络上也有一些这类型的例子,但是写的根本就是错误的,让我看了好久都没明白怎么回事。
这个例子运行时看似是正确的,但是如果把那个对象foreach两次就会出错。因为在foreach第二次的时候,index已经到了最大值。

所以,大家可以参考MSDN的例子,运行都是正常,并且代码看起来更优雅。


posted @ 2009-10-09 14:40  九道轮回  阅读(699)  评论(1编辑  收藏  举报