Generic Custom STACK Class for Hanoi Problem in C#

Have Created a custom class (Generic) in C# for Hanoi Problem. and I am not sure I did a correct thing. please someone could help me with this.

Have created a custom class for this

[DebuggerDisplay("Count = {Count}")]     [System.Runtime.InteropServices.ComVisible(false)]     public class HanoiStack<T> : IEnumerable<T>, ICollection, IEnumerable where T : IHanoiStack     {         private T[] _array;     // Storage for stack elements         private int _size;           // Number of items in the stack.         private int _version;        // Used to keep enumerator in sync w/ collection.         private Object _syncRoot;          private const int _defaultCapacity = 4;         static T[] _emptyArray = new T[0];          public HanoiStack()         {             _array = _emptyArray;             _size = 0;             _version = 0;         }          public HanoiStack(int capacity)         {             if (capacity < 0)                 throw new ArgumentOutOfRangeException("Negative Value Exception");             _array = new T[capacity];             _size = 0;             _version = 0;         }          public HanoiStack(IEnumerable<T> collection)         {             if (collection == null)                 throw new ArgumentException("Null Collection");              ICollection<T> c = collection as ICollection<T>;             if (c != null)             {                 int count = c.Count;                 _array = new T[count];                 c.CopyTo(_array, 0);                 _size = count;             }             else             {                 _size = 0;                 _array = new T[_defaultCapacity];                  using (IEnumerator<T> en = collection.GetEnumerator())                 {                     while (en.MoveNext())                     {                         Push(en.Current);                     }                 }             }         }          public int Count         {             get { return _size; }         }          bool System.Collections.ICollection.IsSynchronized         {             get { return false; }         }          Object System.Collections.ICollection.SyncRoot         {             get             {                 if (_syncRoot == null)                 {                     System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);                 }                 return _syncRoot;             }         }          public void Clear()         {             Array.Clear(_array, 0, _size);             _size = 0;             _version++;         }          public bool Contains(T item)         {             int count = _size;              EqualityComparer<T> c = EqualityComparer<T>.Default;             while (count-- > 0)             {                 if (((Object)item) == null)                 {                     if (((Object)_array[count]) == null)                         return true;                 }                 else if (_array[count] != null && c.Equals(_array[count], item))                 {                     return true;                 }             }             return false;         }          public void CopyTo(T[] array, int arrayIndex)         {             if (array == null)             {                 throw new ArgumentNullException("Null Array");             }              if (arrayIndex < 0 || arrayIndex > array.Length)             {                 throw new ArgumentOutOfRangeException("Negative Argument Exception");             }              if (array.Length - arrayIndex < _size)             {                 throw new ArgumentException("Invalid Argument");             }              Array.Copy(_array, 0, array, arrayIndex, _size);             Array.Reverse(array, arrayIndex, _size);         }          void System.Collections.ICollection.CopyTo(Array array, int arrayIndex)         {             if (array == null)             {                 throw new ArgumentNullException("Array Null Exception");             }              if (array.Rank != 1)             {                 throw new ArgumentException("Rank Multiple Supported");             }              if (array.GetLowerBound(0) != 0)             {                 throw new ArgumentException("Negative Value Exception");             }              if (arrayIndex < 0 || arrayIndex > array.Length)             {                 throw new ArgumentOutOfRangeException("Negative Value Exception");             }              if (array.Length - arrayIndex < _size)             {                 throw new ArgumentException("Invalid Argument");             }              try             {                 Array.Copy(_array, 0, array, arrayIndex, _size);                 Array.Reverse(array, arrayIndex, _size);             }             catch (ArrayTypeMismatchException)             {                 throw new ArgumentException("Argument Invalid Exception");             }         }          public Enumerator GetEnumerator()         {             return new Enumerator(this);         }          IEnumerator<T> IEnumerable<T>.GetEnumerator()         {             return new Enumerator(this);         }          System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()         {             return new Enumerator(this);         }          public void TrimExcess()         {             int threshold = (int)(((double)_array.Length) * 0.9);             if (_size < threshold)             {                 T[] newarray = new T[_size];                 Array.Copy(_array, 0, newarray, 0, _size);                 _array = newarray;                 _version++;             }         }          public T Peek()         {             if (_size == 0)                 throw new Exception("Stack Hanoi is Empty");             return _array[_size - 1];         }          public T Pop()         {             if (_size == 0)                 throw new InvalidOperationException("Stack Hanoi is Empty");             _version++;             T item = _array[--_size];             _array[_size] = default(T);     // Free memory quicker.             return item;         }          public void Push(T item)         {             if (_size > 0)             {                 var _newItem = (IHanoiStack)item;                 var _currentItem = (IHanoiStack)this.Peek();                 if (_currentItem.Height > _newItem.Height)                 {                     throw new InvalidOperationException("Height of the previous item is lesser than the new item.");                 }                 if (_currentItem.Weigth > _newItem.Weigth)                 {                     throw new InvalidOperationException("Weigth of the previous item is lesser than the new item.");                 }             }             if (_size == _array.Length)             {                  T[] newArray = new T[(_array.Length == 0) ? _defaultCapacity : 2 * _array.Length];                 Array.Copy(_array, 0, newArray, 0, _size);                 _array = newArray;             }             _array[_size++] = item;             _version++;         }          public T[] ToArray()         {             T[] objArray = new T[_size];             int i = 0;             while (i < _size)             {                 objArray[i] = _array[_size - i - 1];                 i++;             }             return objArray;         }          public struct Enumerator : IEnumerator<T>,             System.Collections.IEnumerator         {             private HanoiStack<T> _stack;             private int _index;             private int _version;             private T currentElement;              internal Enumerator(HanoiStack<T> stack)             {                 _stack = stack;                 _version = _stack._version;                 _index = -2;                 currentElement = default(T);             }              public void Dispose()             {                 _index = -1;             }              public bool MoveNext()             {                 bool retval;                 if (_version != _stack._version) throw new InvalidOperationException("Stack Hanoi is Empty");                 if (_index == -2)                 {  // First call to enumerator.                     _index = _stack._size - 1;                     retval = (_index >= 0);                     if (retval)                         currentElement = _stack._array[_index];                     return retval;                 }                 if (_index == -1)                 {  // End of enumeration.                     return false;                 }                  retval = (--_index >= 0);                 if (retval)                     currentElement = _stack._array[_index];                 else                     currentElement = default(T);                 return retval;             }              public T Current             {                 get                 {                     if (_index == -2) throw new InvalidOperationException("EnumNotStarted");                     if (_index == -1) throw new InvalidOperationException("EnumEnded");                     return currentElement;                 }             }              Object System.Collections.IEnumerator.Current             {                 get                 {                     if (_index == -2) throw new InvalidOperationException("EnumNotStarted");                     if (_index == -1) throw new InvalidOperationException("EnumEnded");                     return currentElement;                 }             }              void System.Collections.IEnumerator.Reset()             {                 if (_version != _stack._version) throw new InvalidOperationException("EnumFailedVersion");                 _index = -2;                 currentElement = default(T);             }         }     }      public interface IHanoiStack     {         double Height { get; }         double Weigth { get; }     } 

I am trying to do a Generic class for the Hanoi problem. might be simple for someone but I have created this in learning the C# Generics. so I have included the code with this. please help me to validate the code.

  1. The Hanoi problem. this will have a disk of size (n) in a pole and it should be shifted to another among the 3 poles available. But the disk should be in the same other when it was in the previous pole. (Correct?)

  2. I kind of taught that the “STACK” would help me but it will allow the user to add items in any other. So I created an Interface that has Width and Height of the Disk so that I could validate the order based on that Interface.

  3. I have a question here, is this the correct way to do this or I was wrong.