I was looking through my code and I found a couple of extension methods that I wrote in order to remove items from a System.Collections.Generic.Stack. I was curious, so I looked at the source of Stack with Reflector and I can see that they implemented it as an array instead of a linked list and I'm just wondering why? With a linked list there would be no need to resize an internal array...
Here are my extensions, any criticisms or suggestions are welcome. Thanks.
public static Stack<T> Remove<T>(this Stack<T> stack, T item)
{
Stack<T> newStack = new Stack<T>();
EqualityComparer<T> eqc = EqualityComparer<T>.Default;
foreach( T newItem in stack.Reverse() )
{
if( !eqc.Equals(newItem, item) )
{
newStack.Push(newItem);
}
}
return newStack;
}
/// <summary>
/// Returns a new Stack{T} with one or more items removed, based on the given predicate.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="stack"></param>
/// <param name="fnRemove"></param>
/// <returns>The new stack.</returns>
/// <remarks>
/// We have to turn tricks in order to save the LIFO order of the pool
/// since there is no built-in remove method since they implement a Stack internally
/// as an array instead of a linked list. Maybe they have a good reason, I don't know...
///
/// So, to fix this I'm just using a LINQ extension method to enumerate in reverse.
/// </remarks>
public static Stack<T> RemoveWhere<T>(this Stack<T> stack, Predicate<T> fnRemove)
{
Stack<T> newStack = new Stack<T>();
foreach( T newItem in stack.Reverse() )
{
/// Check using the caller's method.
if( fnRemove(newItem) )
{
/// It's not allowed in the new stack.
continue;
}
newStack.Push(newItem);
}
return newStack;
}