I am currently doing some C# Unit-Testing using an Udemy Course. In this course, the current Stack class is implemented:
namespace Testing
{
public class Stack<T>
{
public readonly List<T> _list = new List<T>();
public int Count => _list.Count;
public void Push(T obj)
{
if (obj == null)
throw new ArgumentNullException();
_list.Add(obj);
}
public T Pop()
{
if (_list.Count == 0)
throw new InvalidOperationException();
var result = _list[_list.Count - 1];
_list.RemoveAt(_list.Count - 1);
return result;
}
public T Peek()
{
if (_list.Count == 0)
throw new InvalidOperationException();
return _list[_list.Count - 1];
}
}
}
Now, I do not understand why the Peek function can use
return _list[_list.Count - 1];
As far as I know, A List object cannot be indexed, if such functionality is not explicitly implemented (which does not seem to be the case here). Furthermore, if I create an instance of that object
Stack<int> newStack = new Stack<int>();
newStack.Push(5);
var lastElement = newStack[0];
I get a squiggly error message
cannot apply indexing with to an expression of 'Testing.Stack<int>'
which supports my assumption that this instance cannot be indexed. Can someone please explain me this behavior?
CodePudding user response:
As far as I know, A List object cannot be indexed
This is incorrect. A c# list is a type of dynamic array, similar to the c std::vector
. You are probably thinking of linked list, a completely different type, and one I would rarely recommend using.
cannot apply indexing with to an expression of 'Testing.Stack'
This is because you have not implemented an indexer. Assuming you want zero to be the most recently added item:
public T this[int i] => _list[Count - i - 1];
While writing your own stack can be useful as an exercise, for real work I would recommend using the built in stack. There is also source code available.