【问题标题】:What is the difference between IEnumerator and IEnumerable? [duplicate]IEnumerator 和 IEnumerable 有什么区别? [复制]
【发布时间】:2010-10-11 19:09:44
【问题描述】:

可能重复:
Can anyone explain IEnumerable and IEnumerator to me?

IEnumerator 和 IEnumerable 有什么区别?

【问题讨论】:

标签: c# .net ienumerable ienumerator


【解决方案1】:

IEnumerable 是一个接口,它定义了一个方法 GetEnumerator,它返回一个 IEnumerator 接口,这反过来又允许对集合进行只读访问。实现 IEnumerable 的集合可以与 foreach 语句一起使用。

定义

IEnumerable 

public IEnumerator GetEnumerator();

IEnumerator

public object Current;
public void Reset();
public bool MoveNext();

example code from codebetter.com

【讨论】:

  • 这篇文章可能对您有所帮助。 c-sharpcorner.com/UploadFile/219d4d/…
  • 我想补充一点,实现IEnumerable 以使用带有foreach 语句的类并不是绝对要求。只需要匹配的IEnumerator<T> GetEnumerator() 方法。
  • foreach 循环的实际要求甚至更少限制,并且根本不受这些接口的约束。编译器执行模式匹配。 GetEnumerator 方法只需要返回一个类/结构,该类/结构又具有一个 Current 属性和一个返回 bool 的 MoveNext 方法。我强烈推荐Eric Lipperts blog post about pattern matching
【解决方案2】:

IEnumerator 是一个可以枚举的东西:它具有 Current 属性以及 MoveNextReset 方法(在 .NET 代码中您可能不会显式调用,尽管您可以)。

IEnumerable 是一个可以枚举的东西......这仅仅意味着它有一个 GetEnumerator 方法,该方法返回一个 IEnumerator

你用哪个?使用IEnumerator 的唯一原因是,如果您有某种非标准的枚举方式(即逐个返回其各种元素),并且您需要定义其工作方式。您将创建一个实现IEnumerator 的新类。但是您仍然需要在 IEnumerable 类中返回 IEnumerator

要查看枚举器(实现 IEnumerator<T>)的外观,请参阅任何 Enumerator<T> 类,例如包含在 List<T>Queue<T>,Stack<T> 中的类。要查看实现 IEnumerable 的类,请参阅任何标准集合类。

【讨论】:

  • 那么我们为什么需要这个 IEnumerable 抽象,如果它唯一的作用就是提供对 Enumerator 的访问呢?为什么不直接使用 Enumerator 来代替
  • @xalz,他们做了两件不同的事情。 IEnumerable 回答了这个问题:可以我枚举我的元素吗? IEnumerator 回答了这个问题:如何枚举我的元素?如果您有十个不同的集合,它们都以相同的方式枚举,那么您就不必定义每个集合如何分别枚举。所以你有一个共同的IEnumerator-实现所有十个类,每个集合只需要使用那个枚举类实现IEnumerable。它是关于关注点分离,将持有数据和枚举数据视为单独的操作。
【解决方案3】:

Enumerator 显示列表或集合中的项目。 Enumerator 的每个实例都位于某个位置(第一个元素、第 7 个元素等),并且可以为您提供该元素(IEnumerator.Current)或移动到下一个元素(IEnumerator.MoveNext)。当您在 C# 中编写 foreach 循环时,编译器会生成使用枚举器的代码。

Enumerable 是一个可以给你Enumerators 的类。它有一个名为GetEnumerator 的方法,它为您提供了一个查看其项目的Enumerator。当您在 C# 中编写 foreach 循环时,它生成的代码会调用 GetEnumerator 来创建循环使用的 Enumerator

【讨论】:

  • 那篇博文相当不准确。
【解决方案4】:

IEnumerableIEnumerator 都是接口。 IEnumerable 只有一种称为GetEnumerator 的方法。此方法返回(因为所有方法都返回包括 void 在内的内容)另一种类型,它是一个接口,该接口是 IEnumerator。当您在任何集合类中实现枚举器逻辑时,您就实现了IEnumerable(通用或非通用)。 IEnumerable 只有一种方法,而IEnumerator 有两种方法(MoveNextReset)和一个属性Current。为了便于理解,将IEnumerable 视为一个包含IEnumerator 的盒子(尽管不是通过继承或包含)。查看代码以更好地理解:

class Test : IEnumerable, IEnumerator
{
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }

    public object Current
    {
        get { throw new NotImplementedException(); }
    }

    public bool MoveNext()
    {
        throw new NotImplementedException();
    }

    public void Reset()
    {
        throw new NotImplementedException();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-26
    • 2010-09-29
    • 2015-11-23
    • 2013-02-13
    • 2011-04-26
    • 2016-09-24
    • 1970-01-01
    相关资源
    最近更新 更多