In C#, the LinkedList(T) class does not implement the IList(T) interface. However, the List(T) class does implement IList(T). Why is 开发者_Python百科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).
IList<T>
interface contains an indexer, the indexer is not a functionality you expect on a 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).
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.
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.
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.
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.
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.
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.
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.
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).
Not implementing IList because some operations have poorer complexity than what some people would expect, is wrong in my opinion.
LinkedList is actually a widely-known list data structure which has following operation complexity:
Insertion: O(N)
Removal: O(1)
Indexing: O(N)
Whereas List is a continuos array, which has following algorithm complexity:
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.
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.
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.
Historical quirk: in .NET 1.1 an ArrayList was the class that acts like a dynamic length array.
In .NET 2+ still, List internally organizes as an array. This means that IList expects Array semantics, really.
In .NET, Lists are like arrays, not lists.... (boing)
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)
A linked list is not a data structure that is designed to be accessed by index, however, IList<T>
provides index access capabilities.
So, as you can't access items in a linked list by index, you can't provide methods that try to do that.
Because accessing a linked list by index is not O(1).
精彩评论