为什么C#LinkedList.RemoveFirst()没有返回删除的值?

时间:2011-05-12 18:25:39

标签: c# collections api-design

为什么C#的LinkedList的RemoveFirst()和RemoveLast()操作不会返回删除的值,是否存在一些惯用,性能或设计理念?

现在,如果我想阅读并删除第一个值,我相信咒语是:

LinkedList<string> list = ...;
...
string removed = list.First.Value;
list.RemoveFirst();

在Java中,它将是:

LinkedList<String> list = ...;
...
String removed = list.removeFirst();

别误会我的意思;我并不是说Java更好。只需将Node公开为公共构造,C#的LinkedList就有了更多的可供性。我想了解设计选择。

4 个答案:

答案 0 :(得分:8)

我无法给出明确的答案,因为我无法读懂LinkedList<T>的设计师的想法。我可以说的是这个。

在Java中,LinkedList<E>类实现了Queue<E>接口,它反映了设计者的决定:“你知道吗?链接列表可以很容易地用作队列,所以我们不妨让它实现那个界面。“与队列交互的方式是通过弹出项目,然后,你知道,使用它们的东西(这意味着它是{{1 - 像返回弹出元素的操作一样。)

在.NET中,没有Pop接口。基本上,设计师做出了不同的决定:“我们所知道的最有效的类似队列行为的实现是一个简单的基于数组的循环队列。所以如果开发人员想要一个队列,他们应该使用IQueue<T>类,就是这样。“

如果开发人员想要使用Queue<T>作为队列(或 deque ),那么他/她可能选错了实现他/她实际需要的数据结构(从.NET的角度来看)。

因此,本着“正确的功能应该完成一件事”的精神,BCL人员选择让LinkedList<T>做到这一点:删除第一个元素(类似于LinkedList<T>.RemoveFirst刚删除的方式指定索引处的元素并且不返回任何内容。

我不是说这两个决定是对还是错。我认为Java和.NET中标准链表类的不同接口只是反映了链接列表 的不同视图以及它在两个框架中应该如何使用

答案 1 :(得分:2)

程序员在删除时可能并不总是想要返回第一个节点。如果RemoveFirst返回节点而程序员不需要它,则仍需要内存分配和处理。在我看来,可选地存储第一个节点(使用First属性)并具有单独的删除功能似乎更灵活。

答案 2 :(得分:1)

您是否考虑过使用Queue或Stack集合而不是LinkedList?然后,您可以按下并弹出并获得您想要的行为。

答案 3 :(得分:0)

RemoveFirstRemoveLast实际上没有返回值的原因是LinkedList<T>在内部将节点存储为LinkedListNode<T>LinkedListNode对象具有NextPrevious的概念,但如果从父集合中删除对象,这些属性指向哪里?