【发布时间】:2010-10-11 19:09:44
【问题描述】:
【问题讨论】:
标签: c# .net ienumerable ienumerator
【问题讨论】:
标签: c# .net ienumerable ienumerator
IEnumerable 是一个接口,它定义了一个方法 GetEnumerator,它返回一个 IEnumerator 接口,这反过来又允许对集合进行只读访问。实现 IEnumerable 的集合可以与 foreach 语句一起使用。
定义
IEnumerable
public IEnumerator GetEnumerator();
IEnumerator
public object Current;
public void Reset();
public bool MoveNext();
【讨论】:
IEnumerable 以使用带有foreach 语句的类并不是绝对要求。只需要匹配的IEnumerator<T> GetEnumerator() 方法。
IEnumerator 是一个可以枚举的东西:它具有 Current 属性以及 MoveNext 和 Reset 方法(在 .NET 代码中您可能不会显式调用,尽管您可以)。
IEnumerable 是一个可以枚举的东西......这仅仅意味着它有一个 GetEnumerator 方法,该方法返回一个 IEnumerator。
你用哪个?使用IEnumerator 的唯一原因是,如果您有某种非标准的枚举方式(即逐个返回其各种元素),并且您需要定义其工作方式。您将创建一个实现IEnumerator 的新类。但是您仍然需要在 IEnumerable 类中返回 IEnumerator。
要查看枚举器(实现 IEnumerator<T>)的外观,请参阅任何 Enumerator<T> 类,例如包含在 List<T>、Queue<T>, 或 Stack<T> 中的类。要查看实现 IEnumerable 的类,请参阅任何标准集合类。
【讨论】:
IEnumerable 回答了这个问题:可以我枚举我的元素吗? IEnumerator 回答了这个问题:如何枚举我的元素?如果您有十个不同的集合,它们都以相同的方式枚举,那么您就不必定义每个集合如何分别枚举。所以你有一个共同的IEnumerator-实现所有十个类,每个集合只需要使用那个枚举类实现IEnumerable。它是关于关注点分离,将持有数据和枚举数据视为单独的操作。
Enumerator 显示列表或集合中的项目。
Enumerator 的每个实例都位于某个位置(第一个元素、第 7 个元素等),并且可以为您提供该元素(IEnumerator.Current)或移动到下一个元素(IEnumerator.MoveNext)。当您在 C# 中编写 foreach 循环时,编译器会生成使用枚举器的代码。
Enumerable 是一个可以给你Enumerators 的类。它有一个名为GetEnumerator 的方法,它为您提供了一个查看其项目的Enumerator。当您在 C# 中编写 foreach 循环时,它生成的代码会调用 GetEnumerator 来创建循环使用的 Enumerator。
【讨论】:
IEnumerable 和 IEnumerator 都是接口。 IEnumerable 只有一种称为GetEnumerator 的方法。此方法返回(因为所有方法都返回包括 void 在内的内容)另一种类型,它是一个接口,该接口是 IEnumerator。当您在任何集合类中实现枚举器逻辑时,您就实现了IEnumerable(通用或非通用)。 IEnumerable 只有一种方法,而IEnumerator 有两种方法(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();
}
}
【讨论】: