Прежде всего, просто дайте, что я действительно хочу функциональность Queue<T>
- FIFO, как правило, нужно только Enqueue
/Dequeue
и т.д. - и поэтому я бы предпочел ответить другим чем "То, что вы действительно хотите, это List<T>
" (я знаю о RemoveAt
).
Например, скажем, у меня есть Queue<DataPoint> dataToProcess
точек данных, которые нужно обрабатывать в том порядке, в котором они были получены. Затем периодически было бы целесообразно иметь такой код:
while (dataToProcess.Count > 0) {
DataPoint pointToProcess = dataToProcess.Dequeue();
ProcessDataPoint(pointToProcess);
}
Но тогда предположим, что по какой-то причине он обнаружил, что конкретная точка данных, добавленная в очередь, не должна обрабатываться. Тогда было бы идеально, если бы существовал метод, аналогичный:
dataToProcess.Remove(badPoint);
Я понимаю, что действительно невозможно реализовать метод Remove
, который не включает некоторую форму перечисления; однако, поскольку Queue<T>
на самом деле не позволяет вам просто войти и удалить случайный случай, единственным решением, которое я мог бы выяснить, было следующее:
bool Remove(T item) {
bool itemFound = false;
// set up a temporary queue to take items out
// one by one
Queue<T> receivingQueue = new Queue<T>();
// move all non-matching items out into the
// temporary queue
while (this.Count > 0) {
T next = this.Dequeue();
if (next.Equals(item)) {
itemFound = true;
} else {
receivingQueue.Enqueue(next);
}
}
// return the items back into the original
// queue
while (receivingQueue.Count > 0) {
this.Enqueue(receivingQueue.Dequeue());
}
return itemFound;
}
Это смешно? Это, конечно, выглядит плохо, но я не могу увидеть лучший способ, кроме написания пользовательского класса. И даже тогда лучший способ, с помощью которого я мог бы реализовать метод Remove
, - это использовать LinkedList<T>
внутренне.