public class Stack<T>
{
   readonly int mMaxSize; 
   int mTop = 0;
   T[] mElements;
   public Stack():this(100)  
   {
   }

   public Stack(int size)
   {
      mMaxSize = size;
      mElements = new T[mMaxSize];
   }

   public bool Empty()
   {
       return mTop == 0;
   }

   public override string ToString()
   {
       if (mTop == 0)
       {
           return "<empty stack>";
       }
       string returnString = mElements[0].ToString();
       for (int i = 1; i < mTop; i++)
       {
           returnString = mElements[i].ToString() + ":" + returnString;
       }
       return returnString;
   }

   public void Push(T item)
   {
      if (mTop >= mMaxSize)  
         throw new System.StackOverflowException();
      mElements[mTop++] = item;
   }
   public T Pop()
   {
      mTop--;
      if(mTop >= 0)
      {
         return mElements[mTop];
      }
      else
      {
         mTop = 0;
         throw new System.InvalidOperationException("Cannot pop an empty stack");
      }
   }

}
    // We cannot have a main program in a templated class, so we need
   //  to add another dummy class to hold our main
    class Program
    {

        public static void Main(String[] args)
        {
            Stack<int> stack = new Stack<int>();
            stack.Push(1);
            stack.Push(2);
            Console.WriteLine(stack);
            
            Stack<String> sstack = new Stack<String>();
            sstack.Push("Hello");
            sstack.Push("There");
            Console.WriteLine(sstack);
            Console.ReadKey();
        }
    }