简体   繁体   English

为什么使用数组而不是链接列表实现IEnumerable(或IList)?

[英]Why is an IEnumerable(or IList) implemented using arrays instead of Linked Lists?

I was reading basic tutorials on implementing the methods of the interface IENumerable and found out that all examples use arrays. 我在阅读有关实现IENumerable接口方法的基本教程,发现所有示例都使用数组。 I was under the impression that an IENumerable is essentially very similar to a linked list. 我觉得IENumerable本质上与链接列表非常相似。 And I am fairly confident that an array and a linked list are two completely different data structures. 我非常有信心,数组和链表是两个完全不同的数据结构。

So then why is one (a linked list) being implemented using the other (an array) when we actually argue that they are quite different? 那么,当我们实际上认为它们(完全不同)时,为什么要使用另一个(数组)来实现一个(链接列表)呢?

This is how the code looks like on MSDN page: 这是代码在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);
    }
}

Is there an implementation of IENumerable that I have missed? 我错过了IENumerable的实现吗?

Edit: I now understand that IENumerable doesn't necessarily resemble a linked list. 编辑:我现在知道IENumerable不一定类似于链接列表。 However, this code from MSDN implements an IList using an array: 但是,来自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...
}

I was under the impression that an IENumerable is essentially very similar to a linked list. 我觉得IENumerable本质上与链接列表非常相似。

I'm not really sure where you got that impression. 我不太确定您对此印象如何。 An object implementing IEnumerable or IEnumerable<T> means "this object exposes an enumerator, which makes it iteratable" , it has nothing to do directly to an implementation of a linked list, or an array. 实现IEnumerableIEnumerable<T> 对象的意思是“此对象公开枚举器,从而使其可迭代” ,它与链接列表或数组的实现没有直接关系。 They do both share the common feature of being iteratable. 它们确实具有可迭代的共同特征。 It is a binding contract to the caller. 它是对调用者的有约束力的合同。

So then why is one (a linked list) being implemented using the other (an array) when we actually argue that they are quite different? 那么,当我们实际上认为它们(完全不同)时,为什么要使用另一个(数组)来实现一个(链接列表)呢?

A linked list can have an array as it's storage as an implementation detail , though that would definitely be a poor design choice. 链表在存储为实现细节时可以具有一个数组,尽管这绝对不是一个好的设计选择。

You may note that List<T> also uses an array as it's internal storage, which it re-sizes once it hits the maximum size of the internal array. 您可能会注意到List<T>也使用数组作为内部存储,一旦达到内部数组的最大大小,它就会重新调整大小。

IEnumerable and IEnumerable<T> are not linked lists. IEnumerableIEnumerable<T>不是链接列表。 They are interfaces that provide access to enumeration. 它们是提供对枚举的访问的接口。

Think of it this way: IEnumerable is a promise to deliver 0-n values on enumeration (for example by using foreach ). 这样想:IEnumerable是一个在枚举时提供0-n值的承诺(例如,通过使用foreach )。

Many real classes can fulfill this promise. 许多真实的阶级都可以实现这一诺言。 Lists do, arrays do, collections of all kinds do, your own classes may if you program them to do so. 列表可以,数组可以,各种集合都可以,如果对它们进行编程,您自己的类也可以。 How you get stuff into or out of your container is container specific, IEnumerable only says something about how to get data from your container to do something with it. IEnumerable只说如何将内容放入容器或容器中取出的内容,它仅说明了如何容器中获取数据以对其进行处理。

That's a very easy explanation, you may want to read about deferred execution later when you got this concept down. 这是一个非常简单的解释,当您将此概念付诸实践后,您可能想在以后阅读有关延迟执行的信息

The short answer: IEnumerable is "similar to" a linked list only in that it defines a sequence of values. 简短的答案: IEnumerable与链表“相似”仅在于它定义了一系列值。 But a sequence of values can be defined in any number of other ways as well, including as an array. 但是,也可以通过许多其他方式(包括数组)来定义值序列。

The IEnumerable type is an interface . IEnumerable类型是一个接口 It dictates only what something must expose publicly; 它仅规定必须公开公开的内容; it doesn't in any specific way dictate what the implementation should be. 它并没有以任何特定的方式指示实现应该是什么。

In the case of IEnumerable , the only thing something that implements that interface must do is implement a method named GetEnumerator() , which must return an instance of another interface, IEnumerator . 对于IEnumerable ,实现该接口的唯一要做的事情就是实现一个名为GetEnumerator()的方法,该方法必须返回另一个接口IEnumerator的实例。 That interface must in turn implement a property named Current , which returns an instance of object , and a method named MoveNext() which informs the IEnumerator object to select the next item in the enumeration. 该接口必须依次实现一个名为Current的属性,该属性返回object一个实例,以及一个名为MoveNext()的方法,该方法通知IEnumerator对象选择枚举中的下一项。

(The interface also requires implementation of a Reset() method, but many implementations of the interface just throw NotSupportedException for that method…the Current and MoveNext() members are the minimum to make a useful implementation of the interface). (该接口还需要实现Reset()方法,但是该接口的许多实现只是对该方法抛出NotSupportedExceptionCurrentMoveNext()成员是实现该接口的有用实现的最低要求)。

The enumeration can be implemented in whatever manner is suitable for the object implementing it. 枚举可以以适合于实现该枚举的对象的任何方式实现。 The System.Linq.Enumerable type even includes implementations that simply repeat the same value some number of times, or which emits a sequence of integers. System.Linq.Enumerable类型甚至包括一些实现,这些实现只是重复几次相同的值,或者发出整数序列。 None of the members of that type store an enumeration per se; 该类型的成员本身均不存储枚举; they either create one from scratch, or transform some existing one. 他们要么从头开始创建一个,要么转换一些现有的。

Likewise, you could enumerate lines of text in a file, or pick numbers at random, or reverse the elements of an array. 同样,您可以枚举文件中的文本行,或随机选择数字,或反转数组的元素。 The only thing that matters is that you have some mechanism to choose a sequence of values. 唯一重要的是您具有某种机制来选择值的序列。

The example you posted doesn't actually show us the implementation of IEnumerator …there's some unknown class named PeopleEnum that handles the enumeration. 您发布的示例实际上并未向我们展示IEnumerator的实现…存在一个名为PeopleEnum的未知类来处理枚举。 Presumably, this class simply stores an index into the array of the object passed to it, returning each element in sequence (it could also be implemented using an "iterator method" , but it wouldn't need a whole other type to accomplish that, so I'm guessing it wasn't). 大概,此类仅将索引存储到传递给它的对象的数组中,按顺序返回每个元素(也可以使用“迭代器方法”实现 ,但不需要其他类型即可完成此操作,所以我猜不是)。

I hope the above helps more than confuses. 我希望以上内容能给您带来更多的帮助。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM