I have found more than one occasions where a generic collection needs to be treated as a list at one point in time and as a stack or queue at another time. For an an application I'm currently developing, it does not make sense to use three separate objects.
The simplest solution I could think of was to implement Queue/Dequeue/Push/Pop/Peek functions on the standard List. Also (not included in the code below), an interface constraint is applied on T allowing the class to maintains a position/ordinal index for each list, queue and stack.
public class List<T>:
System.Collections.Generic.List<T>
{
private object SyncRoot = new object();
public void Enqueue (T item)
{
lock (this.SyncRoot)
{
this.Add(item);
}
}
public T Dequeue ()
{
T item = default(T);
lock (this.SyncRoot)
{
if (this.Count > 0)
{
item = this [0];
this.RemoveAt(0);
}
}
return (item);
}
public void Push (T item)
{
lock (this.SyncRoot)
{
this.Add(item);
}
}
public T Pop ()
{
T item = default(T);
lock (this.SyncRoot)
{
if (this.Count > 0)
{
item = this [this.Count - 1];
this.RemoveAt(this.Count - 1);
}
}
return (item);
}
public T PeekQueue ()
{
T item = default(T);
lock (this.SyncRoot)
{
if (this.Count > 0)
{
item = this [0];
}
}
return (item);
}
public T PeekStack ()
{
T item = default(T);
lock (this.SyncRoot)
{
if (this.Count > 0)
{
item = this [this.Count - 1];
}
}
return (item);
}
}
- Since this is a rough, on-the-fly implementation, I'm not sure what corner cases to look out for so would appreciate pointers or links to any existing such implementations.
- Secondly, I am skeptical about performance on very large lists. Is the decision to inherit from List better than using say LinkedList for large lists. In my case, adding/removing items has more priority than enumerating the list.