有人能给我解释一下IEnumerable和IEnumerator吗?

例如,什么时候用它胜过foreach?IEnumerable和IEnumerator的区别是什么?为什么我们需要使用它?


当前回答

实现IEnumerable可以让你获得一个列表的IEnumerator。

IEnumerator允许使用yield关键字以foreach样式顺序访问列表中的项。

在foreach实现之前(例如在Java 1.4中),迭代列表的方法是从列表中获取一个枚举器,然后向它请求列表中的“下一个”项,只要作为下一个项返回的值不为空。Foreach只是隐式地将其作为一种语言特性来实现,与lock()在幕后实现Monitor类的方式相同。

我期望foreach工作在列表上,因为它们实现了IEnumerable。

其他回答

实现IEnumerable的对象允许其他人访问它的每一项(通过枚举器)。 实现IEnumerator的对象是在进行迭代。它循环遍历一个可枚举对象。

可以把可枚举对象想象成列表、堆栈、树。

实现IEnumerable意味着你的类返回一个IEnumerator对象:

public class People : IEnumerable
{
    IEnumerator IEnumerable.GetEnumerator()
    {
        // return a PeopleEnumerator
    }
}

实现IEnumerator意味着你的类返回迭代的方法和属性:

public class PeopleEnumerator : IEnumerator
{
    public void Reset()...

    public bool MoveNext()...

    public object Current...
}

这就是区别所在。

IEnumerable实现了GetEnumerator。当调用时,该方法将返回一个IEnumerator,它实现了MoveNext, Reset和Current。

因此,当你的类实现IEnumerable时,你是在说你可以调用一个方法(GetEnumerator)并返回一个新的对象(一个IEnumerator),你可以在循环中使用,比如foreach。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Enudemo
{

    class Person
    {
        string name = "";
        int roll;

        public Person(string name, int roll)
        {
            this.name = name;
            this.roll = roll;
        }

        public override string ToString()
        {
            return string.Format("Name : " + name + "\t Roll : " + roll);
        }

    }


    class Demo : IEnumerable
    {
        ArrayList list1 = new ArrayList();

        public Demo()
        {
            list1.Add(new Person("Shahriar", 332));
            list1.Add(new Person("Sujon", 333));
            list1.Add(new Person("Sumona", 334));
            list1.Add(new Person("Shakil", 335));
            list1.Add(new Person("Shruti", 336));
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
           return list1.GetEnumerator();
        }
    }



    class Program
    {
        static void Main(string[] args)
        {
            Demo d = new Demo();  // Notice here. it is simple object but for 
                                //IEnumerator you can get the collection data

            foreach (Person X in d)
            {
                Console.WriteLine(X);
            }

            Console.ReadKey();
        }
    }
}
/*
Output : 

Name : Shahriar  Roll : 332
Name : Sujon     Roll : 333
Name : Sumona    Roll : 334
Name : Shakil    Roll : 335
Name : Shruti    Roll : 336
  */

例如,什么时候用它胜过foreach?

你不用IEnumerable "over" foreach。实现IEnumerable使得使用foreach成为可能。

当你写这样的代码时:

foreach (Foo bar in baz)
{
   ...
}

它在功能上相当于这样写:

IEnumerator bat = baz.GetEnumerator();
while (bat.MoveNext())
{
   bar = (Foo)bat.Current
   ...
}

所谓“功能等效”,我指的是编译器实际将代码转换成的内容。在本例中,除非baz实现了IEnumerable,否则不能在baz上使用foreach。

IEnumerable表示baz实现了该方法

IEnumerator GetEnumerator()

该方法返回的IEnumerator对象必须实现这些方法

bool MoveNext()

and

Object Current()

第一个方法前进到创建枚举器的IEnumerable对象中的下一个对象,如果完成则返回false,第二个方法返回当前对象。

. net中任何你可以迭代的东西都实现了IEnumerable。如果您正在构建自己的类,并且它还没有从实现了IEnumerable的类继承,那么您可以通过实现IEnumerable(并通过创建其新的GetEnumerator方法将返回的枚举器类)使您的类在foreach语句中可用。