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

时间:2010-08-27 13:45:09

标签: c# .net

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

10 个答案:

答案 0 :(得分:27)

IList<T>界面包含一个索引器,索引器不是您在LinkedList上所期望的功能。

List<T>可以确保访问 O(1)LinkedList中的项目,因为它的结构不能提供对 O中项目的访问权限( 1)

答案 1 :(得分:11)

查看linked list的定义,您将理解。

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

  

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

     

链表的主要好处   超过传统的阵列是   链接项目的顺序可能是   不同于数据的顺序   项目存储在内存或磁盘上。   因此,链表允许   插入和删除任何节点   列表中的一个常量   操作次数。

     

另一方面,链表由   他们自己不允许随机访问   数据,或任何形式的有效   索引。因此,许多基本操作    - 例如获取最后一个节点   列表,或找到一个节点   包含给定的数据或定位   应该是新节点的位置   插入 - 可能需要扫描最多   列表元素。

答案 2 :(得分:3)

接口提供三种类型的保证,1种是程序性的,2种是概念性的。

程序保证是您可以调用存在的方法或属性。 .NET强制执行此保证。

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

第二个概念保证也是承诺而不是保证,即方法或财产将像其他情况一样工作。

人们习惯于让IList的索引器以相当快的速度运行 - O(1)或更糟糕的O(log n) - 并打破这个概念上的承诺会导致人们严重使用你的对象。

这里没有具体的规则。您当然可以将IList实现为链接列表,并且遭受O(n)索引获取。您还可以实现链接列表,使其不保留其计数记录(由框架提供的记录)并具有O(n)Count属性。但是人们更有可能使用它。

组件设计的一部分不仅仅是确保工作正常并且运行良好,而是指导它们的使用。实现IList的链表在后一点会失败,因此可以提出一个强有力的论据,即它不会像提供的那样好。

答案 3 :(得分:2)

LinkedList实际上是一种广为人知的列表数据结构,具有以下操作复杂性:

Insertion: O(N)

Removal: O(1)

Indexing: O(N)

而List是一个连续数组,具有以下算法复杂性:

Insertion*: O(1)

Removal*: O(N)

Indexing: O(1)

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

答案 4 :(得分:1)

LinkedList不是List。列表是对象的单个维度集合。 LinkedList是一个节点集合,与Dictionary更紧密地对齐。它的需求与常规List不相似,但更专门用于允许节点遍历和组织行为。

答案 5 :(得分:0)

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

答案 6 :(得分:0)

历史怪癖:在.NET 1.1中,ArrayList是一个类似于动态长度数组的类。

在.NET 2+中,List内部组织为一个数组。这意味着IList确实需要数组语义。

在.NET中,列表类似于数组,而不是列表.... (boing)

真正的链接列表具有恒定的时间插入,删除,但缓慢的枚举和较慢的随机访问。

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

答案 7 :(得分:0)

这让我感到惊讶。传统上,列表只是你可以依赖元素顺序的东西,链表遵循这个,它应该实现IList而不是ICollection(集合不说出有关其元素顺序的任何内容。)

由于某些操作的复杂程度低于某些人的预期,因此我没有实施IList。我认为这是错误的。

答案 8 :(得分:-1)

因为按索引访问链接列表不是O(1)。

答案 9 :(得分:-1)

链接列表不是旨在通过索引访问的数据结构,但IList<T>提供了索引访问功能。

因此,由于您无法通过索引访问链接列表中的项目,因此无法提供尝试执行此操作的方法。