C# Stack with maximum limit
I am writing a web based app at the moment and I am wanting to maintain a history of the persons movements around the site to enable some business logic for handling back button clicks.
I wanted to use a Stack but I did not want to let it get too out of control in memory if people take weird navigation choices around the site. So I wanted a stack that would push on the top but have a maximum limit so that when the maximum was reached the oldest items on the stack just fell out the bottom.
So I wrote the MaxStack. Hope you like it. It uses a generic linked list to implement the stack like interface.
Note its also serializable as I am storing it in session.
(Sorry about the indenting wordpress has mashed it)
MaxStack
using System; using System.Collections.Generic; namespace MyArchitecture { /// <summary> /// Generic stack implementation with a maximum limit /// When something is pushed on the last item is removed from the list /// </summary> [Serializable] public class MaxStack<T> { #region Fields private int _limit; private LinkedList<T> _list; #endregion #region Constructors public MaxStack(int maxSize) { _limit = maxSize; _list = new LinkedList<T>(); } #endregion #region Public Stack Implementation public void Push(T value) { if (_list.Count == _limit) { _list.RemoveLast(); } _list.AddFirst(value); } public T Pop() { if (_list.Count > 0) { T value = _list.First.Value; _list.RemoveFirst(); return value; } else { throw new InvalidOperationException("The Stack is empty"); } } public T Peek() { if (_list.Count > 0) { T value = _list.First.Value; return value; } else { throw new InvalidOperationException("The Stack is empty"); } } public void Clear() { _list.Clear(); } public int Count { get { return _list.Count; } } /// <summary> /// Checks if the top object on the stack matches the value passed in /// </summary> /// <param name="value"></param> /// <returns></returns> public bool IsTop(T value) { bool result = false; if (this.Count > 0) { result = Peek().Equals(value); } return result; } public bool Contains(T value) { bool result = false; if (this.Count > 0) { result = _list.Contains(value); } return result; } public IEnumerator GetEnumerator() { return _list.GetEnumerator(); } #endregion } }
Thanks, very usefull.
Just a little bug :
In the ‘Pop’ method, “T value = _list.Last.Value;” should be replaced by “T value = _list.First.Value;”
Goog pickup, I will have to go and find the site where I was using this and updated it. I have adjusted this back into the original post. Thanks
Hello, I must say thanks for this piece of code.
I you want to do a foreach on the Stack you must implement the IEnumerable Interface.
public IEnumerator GetEnumerator()
{
return _list.GetEnumerator();
}
Good Idea. I have added it to the code..
Note:- the enumeration will effectively “Pop” items off the stack, so if you push Item 1, Item 2 and Item 3 on the stack, when you enumerate through the stack it will return in the order of Item 3, Item 2 and Item 1
Great snippet.
Don’t forget the inherit from IEnumerable
public class MaxStack : IEnumerable
and you’ll need both implmentations of GeteEnumerator