为什么LinkedList(T)不实现IList(T)接口?

时间:2022-09-02 12:02:18

In C#, the LinkedList(T) class does not implement the IList(T) interface. However, the List(T) class does implement IList(T). Why is there this discrepancy? Functionally, they are both lists, so this design choice seems odd. It now becomes difficult to switch implementations from List(T) to LinkedList(T).

在c#中,LinkedList(T)类不实现IList(T)接口。然而,List(T)类确实实现了IList(T)。为什么会有这种差异呢?从功能上讲,它们都是列表,所以这个设计选项看起来很奇怪。现在很难将实现从List(T)切换到LinkedList(T)。

10 个解决方案

#1


26  

IList<T> interface contains an indexer, the indexer is not a functionality you expect on a LinkedList.

IList 接口包含索引器,索引器不是LinkedList上所期望的功能。

List<T> can assure access to items in O(1), LinkedList by definition of it's it structure can't provide access to items in O(1).

List 可以保证访问O(1)中的项目,根据定义,LinkedList的it结构不能提供对O(1)项的访问。

#2


10  

See the definition of a linked list, and you will understand.

请参见链表的定义,您将会理解。

Main issue, LinkedLists can contain circular references, and thus does not have an index.

主要问题是,LinkedLists可以包含循环引用,因此没有索引。

Linked lists are among the simplest and most common data structures; they provide an easy implementation for several important abstract data structures, including stacks, queues, associative arrays, and symbolic expressions.

链表是最简单和最常见的数据结构之一;它们为几个重要的抽象数据结构(包括堆栈、队列、关联数组和符号表达式)提供了一个简单的实现。

The principal benefit of a linked list over a conventional array is that the order of the linked items may be different from the order that the data items are stored in memory or on disk. For that reason, linked lists allow insertion and removal of nodes at any point in the list, with a constant number of operations.

与传统数组相比,链表的主要好处是,链表项的顺序可能与数据项存储在内存或磁盘上的顺序不同。由于这个原因,链接列表允许在列表中的任意点插入和删除节点,操作数保持不变。

On the other hand, linked lists by themselves do not allow random access to the data, or any form of efficient indexing. Thus, many basic operations — such as obtaining the last node of the list, or finding a node that contains a given datum, or locating the place where a new node should be inserted — may require scanning most of the list elements.

另一方面,链表本身不允许对数据进行随机访问,也不允许任何形式的有效索引。因此,许多基本操作——例如获取列表的最后一个节点,或者查找包含给定数据的节点,或者定位应该插入新节点的位置——可能需要扫描大多数列表元素。

#3


3  

There are three types of guarantee given by an interface, 1 programmatic and 2 conceptual.

接口提供三种类型的保证,一种是程序化的,另一种是概念性的。

The programmatic guarantee is that you can call a method or property that exists. .NET enforces this guarantee.

可编程的保证是,您可以调用存在的方法或属性。net执行此保证。

The first conceptual guarantee is that it will work. This is often broken (NotImplementedException and NotSupportedException exist precisely to break this) but there should be a good reason for doing this. Still, it's more a promise than a guarantee.

第一个概念上的保证是它会起作用。这种情况经常被破坏(NotImplementedException和NotSupportedException正是为了打破这种状态而存在),但是这样做应该有一个很好的理由。不过,这更多的是一种承诺,而非保证。

The second conceptual guarantee is also more a promise than a guarantee, which is that the method or property will work much like other cases.

第二个概念上的保证也更多的是一种承诺,而不是保证,即方法或属性与其他情况类似。

People are used to getting on an IList's indexer working in reasonably fast - O(1) or at worse about O(log n) - and breaking that conceptual promise will lead to people using your object badly.

人们习惯于使用IList的索引器,以合理的速度(O(1)或更糟的速度(O(log n))工作,而打破这个概念承诺将导致人们严重地使用您的对象。

There's no concrete rule here. You certainly can implement IList as a linked list, and suffer the O(n) indexed get. You can also implement a linked list in such a way that it doesn't keep a record of its count (as that supplied by the framework does) and have an O(n) Count property. But then people are more likely to use it badly.

这里没有具体的规则。您当然可以将IList实现为一个链表,并使用O(n)索引get。您还可以实现一个链表,这样它就不会保存它的计数记录(就像框架提供的那样),并且有一个O(n) count属性。但人们更有可能严重地使用它。

Part of component design is not just making sure things work and work well, but guiding their use. A linked list that implements IList would fail at the latter point, and hence one could make a strong argument that it would not be as good a design as that offered.

组件设计的一部分不仅是确保事物工作良好,而且指导它们的使用。实现IList的链接列表在后一点上将失败,因此有人可能会强烈地认为,它不会像提供的那样是一个好的设计。

#4


2  

LinkedList is actually a widely-known list data structure which has following operation complexity:

LinkedList实际上是一个已知的列表数据结构,它具有以下操作复杂性:

Insertion: O(N)

Removal: O(1)

Indexing: O(N)

Whereas List is a continuos array, which has following algorithm complexity:

而List是一个continuos数组,算法复杂度如下:

Insertion*: O(1)

Removal*: O(N)

Indexing: O(1)

They do not provide the common interface, cause it will misguide users of the interface and make programs efficiency unpredictable. For more information check out books on algorithms and data structures.

它们不提供公共接口,因为它会误导用户的接口,使程序的效率不可预测。有关更多信息,请参阅有关算法和数据结构的书籍。

#5


1  

The LinkedList is not a List. Lists are singular dimensional collections of objects. A LinkedList is a node collection, more closely aligned with a Dictionary. Its needs are not similar to a regular List but more specialized to allow for the node traversal and organization behaviors.

LinkedList不是一个列表。列表是单一维度的对象集合。LinkedList是一个节点集合,与字典更紧密地对齐。它的需求与常规的列表不相似,而是更加专门化,以允许节点遍历和组织行为。

#6


0  

A linked list is not a data structure that is designed to be accessed by index, however, IList<T> provides index access capabilities.

链表不是设计为通过索引访问的数据结构,但是,IList 提供了索引访问功能。

So, as you can't access items in a linked list by index, you can't provide methods that try to do that.

因此,由于不能按索引访问链表中的项,所以不能提供尝试这样做的方法。

#7


0  

A "List" is data structure terms is not a linked list; it's actually an array -- List item are directly accessible, using the indexer, which is not available (not practical) in a linked list.

“列表”是指数据结构术语不是一个链表;它实际上是一个数组——使用索引器可以直接访问列表项,这在链表中是不可用的(不实用)。

#8


0  

Historical quirk: in .NET 1.1 an ArrayList was the class that acts like a dynamic length array.

历史怪癖:在。net 1.1中,ArrayList是像动态长度数组一样的类。

In .NET 2+ still, List internally organizes as an array. This means that IList expects Array semantics, really.

在。net 2+中,List在内部组织为数组。这意味着IList需要数组语义。

In .NET, Lists are like arrays, not lists.... (boing)

在。net,列表就像数组,而不是列出....(网站)

True linked lists have constant time insertion, deletion, but slow enumeration and slower random access.

真正的链表具有固定的插入时间、删除时间,但枚举速度慢,随机访问速度慢。

Arrays have quick enumeration and random access, but have costly insertion / deletion (O(n) and reallocation can quicly lead to completely different behaviour)

数组具有快速的枚举和随机访问,但是代价高昂的插入/删除(O(n)和重新分配可以快速地导致完全不同的行为)

#9


0  

Because accessing a linked list by index is not O(1).

因为通过索引访问链表不是O(1)。

#10


0  

This caught me by surprise as well.. Traditionally, a list is just something where you can depend on the order of the elements, and a linked list obeys this, and it should implement IList rather than ICollection (a collection does not say anything about the order of its elements).

这也让我很吃惊。传统上,列表是可以依赖于元素的顺序的,一个链表遵循这个顺序,它应该实现IList而不是ICollection(一个集合没有提到它的元素的顺序)。

Not implementing IList because some operations have poorer complexity than what some people would expect, is wrong in my opinion.

在我看来,不实施IList是错误的,因为有些操作的复杂性比人们预期的要低。

#1


26  

IList<T> interface contains an indexer, the indexer is not a functionality you expect on a LinkedList.

IList 接口包含索引器,索引器不是LinkedList上所期望的功能。

List<T> can assure access to items in O(1), LinkedList by definition of it's it structure can't provide access to items in O(1).

List 可以保证访问O(1)中的项目,根据定义,LinkedList的it结构不能提供对O(1)项的访问。

#2


10  

See the definition of a linked list, and you will understand.

请参见链表的定义,您将会理解。

Main issue, LinkedLists can contain circular references, and thus does not have an index.

主要问题是,LinkedLists可以包含循环引用,因此没有索引。

Linked lists are among the simplest and most common data structures; they provide an easy implementation for several important abstract data structures, including stacks, queues, associative arrays, and symbolic expressions.

链表是最简单和最常见的数据结构之一;它们为几个重要的抽象数据结构(包括堆栈、队列、关联数组和符号表达式)提供了一个简单的实现。

The principal benefit of a linked list over a conventional array is that the order of the linked items may be different from the order that the data items are stored in memory or on disk. For that reason, linked lists allow insertion and removal of nodes at any point in the list, with a constant number of operations.

与传统数组相比,链表的主要好处是,链表项的顺序可能与数据项存储在内存或磁盘上的顺序不同。由于这个原因,链接列表允许在列表中的任意点插入和删除节点,操作数保持不变。

On the other hand, linked lists by themselves do not allow random access to the data, or any form of efficient indexing. Thus, many basic operations — such as obtaining the last node of the list, or finding a node that contains a given datum, or locating the place where a new node should be inserted — may require scanning most of the list elements.

另一方面,链表本身不允许对数据进行随机访问,也不允许任何形式的有效索引。因此,许多基本操作——例如获取列表的最后一个节点,或者查找包含给定数据的节点,或者定位应该插入新节点的位置——可能需要扫描大多数列表元素。

#3


3  

There are three types of guarantee given by an interface, 1 programmatic and 2 conceptual.

接口提供三种类型的保证,一种是程序化的,另一种是概念性的。

The programmatic guarantee is that you can call a method or property that exists. .NET enforces this guarantee.

可编程的保证是,您可以调用存在的方法或属性。net执行此保证。

The first conceptual guarantee is that it will work. This is often broken (NotImplementedException and NotSupportedException exist precisely to break this) but there should be a good reason for doing this. Still, it's more a promise than a guarantee.

第一个概念上的保证是它会起作用。这种情况经常被破坏(NotImplementedException和NotSupportedException正是为了打破这种状态而存在),但是这样做应该有一个很好的理由。不过,这更多的是一种承诺,而非保证。

The second conceptual guarantee is also more a promise than a guarantee, which is that the method or property will work much like other cases.

第二个概念上的保证也更多的是一种承诺,而不是保证,即方法或属性与其他情况类似。

People are used to getting on an IList's indexer working in reasonably fast - O(1) or at worse about O(log n) - and breaking that conceptual promise will lead to people using your object badly.

人们习惯于使用IList的索引器,以合理的速度(O(1)或更糟的速度(O(log n))工作,而打破这个概念承诺将导致人们严重地使用您的对象。

There's no concrete rule here. You certainly can implement IList as a linked list, and suffer the O(n) indexed get. You can also implement a linked list in such a way that it doesn't keep a record of its count (as that supplied by the framework does) and have an O(n) Count property. But then people are more likely to use it badly.

这里没有具体的规则。您当然可以将IList实现为一个链表,并使用O(n)索引get。您还可以实现一个链表,这样它就不会保存它的计数记录(就像框架提供的那样),并且有一个O(n) count属性。但人们更有可能严重地使用它。

Part of component design is not just making sure things work and work well, but guiding their use. A linked list that implements IList would fail at the latter point, and hence one could make a strong argument that it would not be as good a design as that offered.

组件设计的一部分不仅是确保事物工作良好,而且指导它们的使用。实现IList的链接列表在后一点上将失败,因此有人可能会强烈地认为,它不会像提供的那样是一个好的设计。

#4


2  

LinkedList is actually a widely-known list data structure which has following operation complexity:

LinkedList实际上是一个已知的列表数据结构,它具有以下操作复杂性:

Insertion: O(N)

Removal: O(1)

Indexing: O(N)

Whereas List is a continuos array, which has following algorithm complexity:

而List是一个continuos数组,算法复杂度如下:

Insertion*: O(1)

Removal*: O(N)

Indexing: O(1)

They do not provide the common interface, cause it will misguide users of the interface and make programs efficiency unpredictable. For more information check out books on algorithms and data structures.

它们不提供公共接口,因为它会误导用户的接口,使程序的效率不可预测。有关更多信息,请参阅有关算法和数据结构的书籍。

#5


1  

The LinkedList is not a List. Lists are singular dimensional collections of objects. A LinkedList is a node collection, more closely aligned with a Dictionary. Its needs are not similar to a regular List but more specialized to allow for the node traversal and organization behaviors.

LinkedList不是一个列表。列表是单一维度的对象集合。LinkedList是一个节点集合,与字典更紧密地对齐。它的需求与常规的列表不相似,而是更加专门化,以允许节点遍历和组织行为。

#6


0  

A linked list is not a data structure that is designed to be accessed by index, however, IList<T> provides index access capabilities.

链表不是设计为通过索引访问的数据结构,但是,IList 提供了索引访问功能。

So, as you can't access items in a linked list by index, you can't provide methods that try to do that.

因此,由于不能按索引访问链表中的项,所以不能提供尝试这样做的方法。

#7


0  

A "List" is data structure terms is not a linked list; it's actually an array -- List item are directly accessible, using the indexer, which is not available (not practical) in a linked list.

“列表”是指数据结构术语不是一个链表;它实际上是一个数组——使用索引器可以直接访问列表项,这在链表中是不可用的(不实用)。

#8


0  

Historical quirk: in .NET 1.1 an ArrayList was the class that acts like a dynamic length array.

历史怪癖:在。net 1.1中,ArrayList是像动态长度数组一样的类。

In .NET 2+ still, List internally organizes as an array. This means that IList expects Array semantics, really.

在。net 2+中,List在内部组织为数组。这意味着IList需要数组语义。

In .NET, Lists are like arrays, not lists.... (boing)

在。net,列表就像数组,而不是列出....(网站)

True linked lists have constant time insertion, deletion, but slow enumeration and slower random access.

真正的链表具有固定的插入时间、删除时间,但枚举速度慢,随机访问速度慢。

Arrays have quick enumeration and random access, but have costly insertion / deletion (O(n) and reallocation can quicly lead to completely different behaviour)

数组具有快速的枚举和随机访问,但是代价高昂的插入/删除(O(n)和重新分配可以快速地导致完全不同的行为)

#9


0  

Because accessing a linked list by index is not O(1).

因为通过索引访问链表不是O(1)。

#10


0  

This caught me by surprise as well.. Traditionally, a list is just something where you can depend on the order of the elements, and a linked list obeys this, and it should implement IList rather than ICollection (a collection does not say anything about the order of its elements).

这也让我很吃惊。传统上,列表是可以依赖于元素的顺序的,一个链表遵循这个顺序,它应该实现IList而不是ICollection(一个集合没有提到它的元素的顺序)。

Not implementing IList because some operations have poorer complexity than what some people would expect, is wrong in my opinion.

在我看来,不实施IList是错误的,因为有些操作的复杂性比人们预期的要低。