Почему C # LinkedList.RemoveFirst () не возвращает удаленное значение? - PullRequest
11 голосов
/ 12 мая 2011

Существует ли какая-то идиоматическая, производительная или конструктивная причина, по которой операции RemoveFirst () и RemoveLast () в C # LinkedList не возвращают удаленное значение?

Прямо сейчас, если я хочу прочитать и удалить первое значение, я считаю, что это заклинание:

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

В Java это будет:

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

Не поймите меня неправильно; Я не пытаюсь сказать, что Java лучше. LinkedList в C # имеет гораздо больше возможностей, просто выставляя Node как публичную конструкцию. Я пытаюсь понять выбор дизайна.

Ответы [ 4 ]

8 голосов
/ 12 мая 2011

Я не могу дать однозначного ответа, поскольку не могу прочитать мысли дизайнеров LinkedList<T>.То, что я могу сказать, таково:

В Java класс LinkedList<E> реализует интерфейс Queue<E>, который отражает решение со стороны дизайнеров: "Знаете что? Aсвязанный список можно легко использовать в качестве очереди, поэтому мы могли бы также использовать его для реализации этого интерфейса ».И способ, которым вы взаимодействуете с очередью , заключается в выталкивании предметов с конца, а затем, вы знаете, с использованием их для чего-то (что означает, что это естественно для Pop -подобногооперация для возврата элемента () (

). В .NET нет интерфейса IQueue<T>.По сути, дизайнеры приняли другое решение: «Наиболее эффективная реализация поведения, похожего на очередь, - это простая круговая очередь на основе массива. Поэтому, если разработчики хотят получить очередь, они должны использовать класс Queue<T>, который точноэто. "

Если разработчик хочет использовать LinkedList<T> в качестве очереди (или deque в этом отношении), скорее всего, он / она выбираетнеправильная реализация структуры данных, в которой он / она действительно нуждается (с точки зрения .NET).

Таким образом, в духе «правильная функция должна делать ровно одну вещь», люди BCL выбралиmake LinkedList<T>.RemoveFirst делает именно это: удаляет первый элемент (аналогично тому, как List<T>.RemoveAt просто удаляет элемент по указанному индексу и ничего не возвращает).

Я не говорю, что решение является правильным или неправильным.Я думаю, что различные интерфейсы стандартного класса связанного списка в Java и .NET просто отражают разные взгляды на то, что связанный список является и как он должен использоваться в двух рамках.

2 голосов
/ 12 мая 2011

Программист может не всегда хотеть вернуть первый узел при его удалении. Если RemoveFirst вернул узел и программисту это не нужно, ему все равно потребуется выделение и удаление памяти. По моему мнению, сохранение первого узла (с использованием свойства First) и наличие отдельной функции удаления кажется более гибким.

1 голос
/ 12 мая 2011

Рассматривали ли вы использование очереди или коллекции стеков вместо LinkedList?затем вы можете нажать и выскочить и получить желаемое поведение.

0 голосов
/ 12 мая 2011

Причина, по которой RemoveFirst и RemoveLast фактически не возвращают значение, заключается в том, что внутренне LinkedList<T> хранит узлы как LinkedListNode<T>.Объект LinkedListNode имеет концепцию Next и Previous, но если вы удалите объект из родительской коллекции, куда будут указывать эти свойства?

...