我正在阅读有关实现IENumerable接口方法的基本教程,并发现所有示例都使用数组。我的印象是IENumerable与链表非常相似。我相信数组和链表是两个完全不同的数据结构。
那么为什么当我们实际认为它们完全不同时,使用另一个(数组)实现一个(链表)?
这是MSDN页面上代码的样子:
// Collection of Person objects. This class
// implements IEnumerable so that it can be used
// with ForEach syntax.
public class People : IEnumerable
{
private Person[] _people;
public People(Person[] pArray)
{
_people = new Person[pArray.Length];
for (int i = 0; i < pArray.Length; i++)
{
_people[i] = pArray[i];
}
}
// Implementation for the GetEnumerator method.
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator) GetEnumerator();
}
public PeopleEnum GetEnumerator()
{
return new PeopleEnum(_people);
}
}
我错过了IENumerable的实现吗?
编辑:我现在明白,IENumerable并不一定像链表。但是,MSDN中的此代码使用数组实现IList:
class SimpleList : IList
{
private object[] _contents = new object[8];
private int _count;
public SimpleList()
{
_count = 0;
}
// IList Members
public int Add(object value)
{
if (_count < _contents.Length)
{
_contents[_count] = value;
_count++;
return (_count - 1);
}
else
{
return -1;
}
}
//etc...
}
答案 0 :(得分:4)
我的印象是IENumerable本质上非常 类似于链表。
我不确定你的印象在哪里。实现IEnumerable
或IEnumerable<T>
的对象意味着“此对象公开了一个枚举器,使其可迭代”,它与链表的实现没有任何关系,或者数组。他们做都具有可迭代的共同特征。这是对来电者的约束性合同。
那么为什么一个(链表)使用另一个来实现呢? (数组)当我们真的认为它们完全不同时?
链接列表可以将数组存储为实现细节,但这肯定是一个糟糕的设计选择。
您可能会注意到List<T>
也使用数组作为内部存储,一旦达到内部数组的最大大小,它就会重新调整大小。
答案 1 :(得分:0)
IEnumerable
和IEnumerable<T>
不是链接列表。它们是提供枚举访问的接口。
以这种方式思考:IEnumerable是一个在枚举时提供0-n值的承诺(例如,通过使用foreach
)。
许多真正的课程都能实现这一承诺。列表,数组,各种集合,如果你为它们编程,你自己的类可以这样做。如何从容器中获取到或 的容器,IEnumerable
只说明了如何从获取数据容器用它来做某事。
这是一个非常简单的解释,您可能希望稍后在阅读此概念时阅读延迟执行。
答案 2 :(得分:0)
简短回答:IEnumerable
与链接列表“相似”只是因为它定义了一系列值。但是,一系列值也可以用许多其他方式定义,包括作为数组。
IEnumerable
类型是interface。它只规定必须公开展示的内容;它没有以任何特定的方式决定实现应该是什么。
在IEnumerable
的情况下,实现该接口必须做的唯一事情是实现名为GetEnumerator()
的方法,该方法必须返回另一个接口IEnumerator
的实例。该接口必须依次实现名为Current
的属性,该属性返回object
的实例,以及名为MoveNext()
的方法,该方法通知IEnumerator
对象选择下一个项目枚举。
(该接口还需要实现Reset()
方法,但是该接口的许多实现只为此方法抛出NotSupportedException
... Current
和MoveNext()
成员是最小化以实现接口的有用实现。)
枚举可以以适合实现它的对象的任何方式实现。 System.Linq.Enumerable
类型甚至包括简单地重复相同值的实现,或者发出一系列整数的实现。该类型成员的无本身存储枚举;他们要么从头开始创建一个,要么改造现有的一个。
同样,您可以枚举文件中的文本行,或随机选择数字,或者反转数组的元素。唯一重要的是你有一些机制来选择一系列的值。
您发布的示例实际上并未向我们显示IEnumerator
的实现...有一些名为PeopleEnum
的未知类处理枚举。据推测,这个类只是将一个索引存储到传递给它的对象的数组中,按顺序返回每个元素(它也可以使用"iterator method"实现,但它不需要一个完整的其他类型来完成,所以我猜它不是。)
我希望上述内容有助于解决问题。 :)