代码之家  ›  专栏  ›  技术社区  ›  GurdeepS

迭代器和枚举器的区别

  •  69
  • GurdeepS  · 技术社区  · 15 年前

    .NET3.5作业的面试问题是“迭代器和枚举器之间的区别是什么?”

    这是一个核心的区别,用LINQ做什么等等。

    不管怎样,有什么区别?我在网上找不到一个确切的定义。别搞错了,我能找到这两个词的意思,但我得到的答案略有不同。面试的最佳答案是什么?

    imo一个迭代器“迭代”一个集合,一个枚举器提供了迭代的功能,但必须调用它。

    另外,使用yield关键字也被称为save state。这个州到底是什么?是否有这种利益发生的例子?

    8 回复  |  直到 6 年前
        1
  •  48
  •   T Graham    11 年前

    迭代意味着重复一些步骤,而枚举意味着遍历值集合中的所有值。所以枚举通常需要某种形式的迭代。

    这样,枚举是迭代的一种特殊情况,其中步骤从集合中获取值。

    注意,“通常”的“枚举”也可以递归执行,但是递归和迭代是如此密切相关,以至于我不关心这个小的差异。

    还可以枚举未显式存储在集合中的值。例如,可以枚举自然数、素数或其他值,但在枚举期间将计算这些值,而不是从物理集合中检索这些值。您将这种情况理解为使用某个逻辑定义的值枚举虚拟集合。


    我想里德·科普西明白了。在C中,有两种主要的枚举方法。

    1. 实施 Enumerable 以及一个实现 IEnumerator
    2. 使用实现迭代器 yield 陈述

    第一种方法很难实现并使用对象进行枚举。第二种方法更容易实现和使用延续。

        2
  •  43
  •   StayOnTarget    6 年前

    C+2+, iterators 是编译器自动为您生成IEnumerable和/或IEnumerable<t>接口的一种方法。

    如果没有迭代器,则需要创建一个类实现 IEnumerator ,包括current、movenext和reset。这需要大量的工作。通常,您将创建一个私有类,该类为您的类型实现IEnumerator<t>,然后您的rclass.getEnumerator()将构造该私有类并返回它。

    迭代器是编译器使用简单语法(yield)自动为您生成它的一种方法。这允许您直接在类中实现getEnumerator(),而不需要您指定第二个类(IEnumerator)。该类及其所有成员的构造都是为您完成的。

    迭代器对开发人员非常友好-事情是以非常有效的方式完成的,而且工作量要少得多。

    当您使用foreach时,两者的行为将相同(前提是您正确地编写自定义IEnumerator)。迭代器只是让生活简单多了。

        3
  •  18
  •   cdiggins    15 年前

    C称之为 迭代器 更常见的是(在C世界之外)被称为 generator 发电机功能 (例如,在python中)。生成器函数是 coroutine . C迭代器(生成器)是 枚举器 (实现 IEnumerable 接口。

    我不喜欢对C生成器使用术语迭代器,因为它和迭代器一样是一个枚举器。不过,微软改变主意为时已晚。

    相比之下,在C++中,迭代器是一个主要用于访问集合中的顺序元素的值。它可以被高级化、去引用以检索值,并进行测试以查看是否已到达集合的结尾。

        4
  •  12
  •   Joshua    15 年前

    为了理解迭代器,我们首先需要了解枚举器。

    枚举器是一种专门的对象,它为一个人提供了一次浏览一个有序的项目列表的方法(同一种事物有时称为光标)。NET框架提供了两个与枚举器相关的重要接口:IEnumerator和IEnumerable。实现IEnumerator的对象本身就是枚举器;它们支持以下成员:

    • 当前属性,该属性指向列表上的位置

    • 方法moveNext,它将当前项沿列表移动一个

    • 方法重置,将当前项移动到其初始位置(位于第一项之前)。

    另一方面,ITER________.NET 2.0引入了ITER_________当枚举对象c______________选项“lly”,ITER___________

    _________ITER__________C__________

    迭代器的要点是允许轻松实现枚举器。当一个方法需要返回一个枚举器或一个可枚举类来获得一个有序的项列表时,它会被写入,以便使用__yield_语句以正确的顺序返回每个项。

        5
  •  11
  •   Ping    10 年前

    foreach语句是枚举器的使用者,而迭代器是枚举器的生产者。

    以上就是“简而言之,C 5.0”如何解释它,并对我有所帮助。

    换句话说,foreach语句使用moveNext()和IEnumerator的current属性来迭代序列,而迭代器用于生成将由foreach语句使用的IEnumerator的实现。在C中,当您编写一个包含yield语句的迭代器方法时,编译器将为您生成一个私有的枚举器。当您遍历序列中的项时,它将调用私有枚举器的moveNext()和current属性。这些方法/属性由迭代器方法中的代码实现,迭代器方法将重复调用这些方法/属性以生成值,直到没有剩余的值可供生成为止。

    这是我对C如何定义枚举器和迭代器的理解。

        6
  •  7
  •   richard    14 年前

    由于没有给出例子,这里有一个对我有帮助的例子。

    枚举器是在实现IEnumerator接口的类或类型上调用.getEnumerator()时获得的对象。实现此接口时,您已经创建了编译器所需的所有代码,以便使用 foreach 对集合进行“迭代”。

    不过,不要把“迭代器”这个词与迭代器混淆。枚举器和迭代器都允许您“迭代器”。枚举和迭代基本上是相同的过程,但实现方式不同。枚举意味着您已经实现了IEnumerator接口。迭代意味着您已经在类中创建了迭代器构造(如下所示),并且正在调用 前额 在类上,此时编译器自动为您创建枚举器功能。

    还要注意,你不必和你的枚举器一起蹲着。你可以打电话 MyClass.GetEnumerator() 整天不做任何事情(例如:

    IEnumerator myEnumeratorThatIWillDoNothingWith = MyClass.GetEnumerator() )

    也请注意,类中的迭代器构造只有在实际使用realy时才会被使用,即 前额 在你们班上。

    下面是一个迭代器示例 msdn :

    public class DaysOfTheWeek : System.Collections.IEnumerable
    {
    
         string[] days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" };
    
         //This is the iterator!!!
         public System.Collections.IEnumerator GetEnumerator()
         {
             for (int i = 0; i < days.Length; i++)
             {
                 yield return days[i];
             }
         }
    
    }
    
    class TestDaysOfTheWeek
    {
        static void Main()
        {
            // Create an instance of the collection class
            DaysOfTheWeek week = new DaysOfTheWeek();
    
            // Iterate with foreach - this is using the iterator!!! When the compiler
            //detects your iterator, it will automatically generate the Current, 
            //MoveNext and Dispose methods of the IEnumerator or IEnumerator<T> interface
            foreach (string day in week)
            {
                System.Console.Write(day + " ");
            }
        }
    }
    // Output: Sun Mon Tue Wed Thr Fri Sat
    
        7
  •  3
  •   John Ellinwood    15 年前

    “迭代器是C 2.0中的一个新功能。迭代器是一个方法、get访问器或运算符,它使您能够支持类或结构中的foreach迭代,而无需实现整个IEnumerable接口。相反,您只提供一个迭代器,它简单地遍历类中的数据结构。当编译器检测到迭代器时,它将自动生成IEnumerable或IEnumerable接口的当前、moveNext和dispose方法。“”- msdn

        8
  •  2
  •   Kredns    15 年前

    枚举处理对象,而迭代仅处理值。当我们在while循环for循环等中使用迭代时,使用向量哈希表等时使用枚举。我从未使用yield关键字,因此我无法告诉您。