IEnumerable 是一个接口,定义了一个方法 GetEnumerator,该方法返回 IEnumerator 接口,这反过来又允许对集合进行只读访问。实现 IEnumerable 的集合可以与 foreach 语句一起使用。
定义
IEnumerable
public IEnumerator GetEnumerator();
IEnumerator
public object Current;
public void Reset();
public bool MoveNext();
IEnumerator
是一个可以枚举的东西:它具有 Current
属性以及 MoveNext
和 Reset
方法(在 .NET 代码中你可能不会显式调用,尽管可以)。
IEnumerable
是一个可以枚举的东西...这仅仅意味着它有一个返回IEnumerator
的GetEnumerator方法。
你用哪个?使用
IEnumerator
的唯一原因是,如果您有一些具有非标准枚举方式(即一一返回其各种元素)的东西,并且您需要定义其工作原理。您将创建一个实现 IEnumerator
的新类。但您仍然需要在 IEnumerator
类中返回 IEnumerable
。
要了解枚举器(实现
IEnumerator<T>
)的外观,请参阅任何 Enumerator<T>
类,例如 List<T>
、Queue<T>,
或 Stack<T>
中包含的类。要查看实现 IEnumerable
的类,请参阅任何标准集合类。
Enumerator
显示列表或集合中的项目。
枚举器的每个实例都位于某个位置(第一个元素、第七个元素等),并且可以为您提供该元素 (IEnumerator.Current
) 或移动到下一个 (IEnumerator.MoveNext
)。当您在 C# 中编写 foreach
循环时,编译器会生成使用枚举器的代码。
Enumerable
是一门可以为您提供 Enumerator
的课程。它有一个名为 GetEnumerator
的方法,它为您提供了一个 Enumerator
来查看其项目。当您在 C# 中编写 foreach
循环时,它生成的代码会调用 GetEnumerator
来创建循环使用的 Enumerator
。
IEnumerable
和 IEnumerator
都是接口。 IEnumerable
只有一种方法,称为 GetEnumerator
。此方法返回(因为所有方法都返回包括 void 在内的内容)另一种类型,该类型是一个接口,并且该接口是 IEnumerator
。当您在任何集合类中实现枚举器逻辑时,您就实现了 IEnumerable
(通用或非通用)。 IEnumerable
只有一种方法,而 IEnumerator
有 2 个方法(MoveNext
和 Reset
)和一个属性 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();
}
}