Search code examples
c#.netlinq

List used as a queue in .net and retain order


I want to use a List as a queue. This is because List is more flexible when getting/inserting data.

My question is when I use Linq operations (DistinctBy, Take) as shown below, do I still get the elements in order they have been added into the list?

private List<IMessage> _queue = new List<IMessage>();

// add many
 _queue.Add(tagMessage);


 toConsume = _queue
     .Where(t => !_snLockList.Contains(t.Id))
     .DistinctBy(t => t.Id)
     .Take(freeTasks).ToList();

Solution

  • The answer is "Yes but...".

    Yes all LINQ operations that iterate over collections using "foreach, yield return pattern" return results in the order of the underlying object's (your List<T>'s) IEnumerable (see MS Doc - yield, also follow link in this article to iterators) - unless/until another operation reorders (Sort()).

    But you do not give enough insight into the "what, how and why" of what you are doing... (1) Lists can be used to implement pretty efficient (ring) queues ("ring buffers" - for which you will probably have to code iterator/s). (2) If you intend inserting into and deleting from the middle of the queue, then you must use (O(n), i.e. pretty expensive) shuffle-up and -down logic (behind the scenes of Insert(), RemoveAt()... and your queue isn't FIFO i.e. isn't really a queue).

    Have you considered using PriorityQueue<T> or LinkedList<T>?