Hoogmin Hoogmin - 3 months ago 10
C# Question

How to Stop getting System.TypeInitializationException everytime I use My stack class

I got a coding exercise in an online C# course where I have to Design my own stack class.
The problem I keep encountering with this code is that it keeps giving me a System.TypeInitializationException for some reason. I have tried changing modifiers but nothing has worked. Any solutions?
Here is the following code:

public class Stack
{
public static List<object> StackStorage = new List<object>();
public static object LastElement = StackStorage[StackStorage.Count - 1];
public static object FirstElement = StackStorage[0];


public void Push(object obj)
{
if (StackStorage.Count - 1 >= 8)
{
StackStorage.Remove(LastElement);
StackStorage.Insert(0, obj);
}
else
{
StackStorage.Add(obj);

}

//Add Logic in here to check whether or not the List count
//Is Longer than 8. Remember that .Count gives you a value NOT
//Zero based. If you want the index of a value you would have
//To do ExampleList.Count - 1.


}
public object Pop()
{
StackStorage.Remove(LastElement);
return LastElement;

}

public void Clear()
{
StackStorage.Clear();


}

public int PrintCount()
{

return StackStorage.Count();


}




}
And the code I have in the main method:
Stack MyStack = new Stack();
MyStack.Push(1);
MyStack.Push(2);
MyStack.Push(3);
Console.WriteLine(MyStack.PrintCount());
Console.ReadKey();

Answer
public static List<object> StackStorage = new List<object>();
public static object LastElement = StackStorage[StackStorage.Count - 1];
public static object FirstElement = StackStorage[0];

are computed once on application start and since StackStorage.Count - 1 is -1 on application start it gives you that exception.

What you really need is to calculate them every time you need access them. For example:

public object GetLastElement(){
  if (StackStorage.Count > 0)
      return StackStorage[StackStorage.Count - 1];
  throw new Exception("Collection is empty");
}
//and so on

But I would not recommend to go this road, better approach would be:

  • get rid of static (as you want stack underlying collection to belong to instance of class not to instace of running process)
  • use indexes
  • use generics

In that case your class would look like:

    public class Stack<T>
    {
        private const int MAX_SIZE = 8;

        private List<T> StackStorage = new List<T>();

        private void RemoveLast()
        {
            StackStorage.RemoveAt(StackStorage.Count - 1);
        }

        public void Push(T obj)
        {
            StackStorage.Insert(0, obj);

            if (StackStorage.Count > MAX_SIZE)
                RemoveLast();
        }

        public T Pop()
        {
            if (StackStorage.Count == 0)
                throw new Exception("Stack is empty");

            T result = StackStorage[StackStorage.Count - 1];
            RemoveLast();

            return result;
        }

        public void Clear()
        {
            StackStorage.Clear();
        }

        public int Count => StackStorage.Count;
    }

And you can use it like:

    Stack<int> MyStack = new Stack<int>();
    MyStack.Push(1);
    MyStack.Push(2);
    MyStack.Push(3);
    Console.WriteLine(MyStack.Count);
    Console.ReadKey();