C# Advance

C# Stack

The objective of this article is to familiarize you with the generic C# Stack, which is implemented via Stack<T> collection class. You will learn how to declare, create, instantiate and use this type of collection, including code examples of the commonly used methods and properties of Stack<> class. Finally, different ways to iterate through all the items of the collection.

C# Stack<T> (generics)

C# Stack is a collection which represents a last-in, first-out (LIFO) mechanism, with methods where an item is added into the stack at the top (Push method) and is removed from the stack at the top (Pop method), meaning you add items at one end and remove them from the same end. You cannot add items in the middle. Sometimes top of the stack is called Head and the bottom is called its Tail.

Stack T Stack-animation

The principal methods are Push and Pop, where the Push method adds an item to the stack, and the Pop method gets the item that was added last.

C# Stack can be implemented with the Stack<T> class in the System.Collections.Generic namespace, where T specifies the type of items in the stack. You cannot use collection initializers with stacks, because collection initializers are implemented using the Add method whereas stack uses Push and Pop methods to add and retrieve items.

Note: Stack allows null with reference type such as string and duplicate values.

Common Properties and Methods of the Stack<T> Class

Mostly used methods of the Stack<T> class to perform different operations are listed below.

Stack-T

You can declare and initialize C# Stack as in the following code.

using Statement

To work with the C# Stack, you need to add the following namespace at the beginning your code:

using System.Collections.Generic;

Declaration and Instantiation Using Two Statements

The T part of the declaration indicates that the class will work with a certain type.

Stack<T> stackName; // declaration

You use new keyword with default constructor to initialize an empty Stack.

stackName = new Stack<T>(); // initialization

You can also use a constructor to specify the capacity. As items are added to the stack, the capacity is automatically increased to hold more items. The capacity is doubled if required.

stackName = new Stack<T>(capacity);

The capacity can be decreased by calling TrimExcess method.

Declaration and Instantiation Combined on a Single Line

Stack<T> stackName = new Stack<T>(); // declaration & initialization

Use of var keyword to infer its type from the value that’s assigned to it.

var stackName = new Stack<T>();

Add Items to a Stack

string[] morePlanets = { "Mercury", "Venus", "Earth" }; // Array
Stack<string> planets; // declaration

Constructor Initialization

You can initialize a new instance of the Stack<T> class that contains items copied from the morePlanets array.

Signature:Stack<T>(IEnumerable<T> collection)

planets = new Stack<string>(morePlanets); // initialization

Stack Constructor Initialization

Run Demo

OUTPUT

Earth
Venus
Mercury

Push()

You can add a new item on the top of the Stack<T> using Push method.

Signature:void Push(T item)

planets = new Stack<string>(morePlanets); // initialization

planets.Push("Mars");
planets.Push("Jupiter");

Stack Push Method

Run Demo

OUTPUT

Jupiter <-
Mars <-
Earth
Venus
Mercury

Remove Stack Items

Stack<string> planets = new Stack<string>();
planets.Push("Mercury");
planets.Push("Venus");
planets.Push("Earth");

Stack Initialization

Pop()

Pop method returns the item at the top of the Stack and removes it from the stack. Calling the Pop method once more removes the next item from the stack. Invoking Pop method on empty stack will throw InvalidOperationException with the message 'Stack empty.'. Always check count property before calling Pop method.

Signature:T Pop()

if (planets.Count > 0)
    planets.Pop();

Stack Pop Method

Run Demo

OUTPUT

Earth

Clear()

The Clear method removes all the items from a Stack<T> and sets its Count property to zero.

Signature:void Clear()

planets.Clear();

Run Demo

Peek(), Contains(), and ToArray() Methods

Stack<string> planets = new Stack<string>();
planets.Push("Mercury");
planets.Push("Venus");
planets.Push("Earth");

Peek()

The Peek method returns the top item from the beginning of the Stack<T> without removing it. Calling the Peek once more retrieves the next item from the stack. If you use Peek on empty stack, run time exception of type InvalidOperationException is thrown with the message 'Stack empty.'

Signature:T Peek()

if (planets.Count > 0)
    planets.Peek();

Stack Peek Method

Run Demo

OUTPUT

Earth

Contains()

The Contains method checks and returns Boolean (True/False) value whether specified item exists in the Stack<T>.

Signature:bool Contains(T item)

planets.Contains("Venus"); // Returns True

Stack Contains Method

Run Demo

OUTPUT

True

ToArray()

Copies the Stack<T> elements to a new array.

Signature:T[] ToArray()

var stackPlanetsArray = planets.ToArray();

Stack ToArray Method

Run Demo

OUTPUT

Earth
Venus
Mercury

Count Property

Stack<string> planets = new Stack<string>();
planets.Push("Mercury");
planets.Push("Venus");

Count

To return total number of items in the stack, use the Count property.

planets.Count; // Returns 2

Run Demo

Processing Stack with Loops

The first statement declares a stack named planets that contains 3 string values.

Stack<string> planets = new Stack<string>();
planets.Push("Mercury");
planets.Push("Venus");
planets.Push("Earth");

Note: It doesn’t matter where you are modifying the collection. If a collection is modified while you are enumerating its members, you get exception.

foreach Loop

If you use foreach to iterate through a Stack<T> collection, you cannot use the iteration variable to modify the contents of the collection. Any attempt to do that will result an exception of type InvalidOperationException with the message 'Collection was modified; enumeration operation may not execute.'

Note: The foreach statement only allows reading from, not writing to, the collection.

foreach (var planet in planets)
    Console.WriteLine(planet);

// iterate a Stack by converting it into an Array
foreach (var planet in planets.ToArray())
    Console.WriteLine(planet);

Run Demo

OUTPUT

Earth
Venus
Mercury

while Loop

Use of while loop to iterate through a Stack<T> collection.

while (planets.Count > 0)
    Console.WriteLine(planets.Pop());
// Namespace Required 
using System.Linq;
while (planets.Any())
    Console.WriteLine(planets.Pop());

Run Demo

OUTPUT

Earth
Venus
Mercury

More Examples

This statement declares and initializes a stack of 3 characters. Once the stack is created, you can add items to the stack with the Push method.

//Array
char[] extraGrade = { 'A', 'B', 'C' };

Stack<char> grades = new Stack<char>(extraGrade);

Stack Constructor Initialization extraGrade

//Push() to add item at the top
grades.Push('D');
grades.Push('E');

Stack Push Method extraGrade

//Peek() to get the highest item
Console.WriteLine(grades.Peek()); // Prints E

Stack Peek Method grades

//Contains()
Console.WriteLine(grades.Contains('B')); // Prints True

Stack Contains Method grades

//Count to get total number of items
Console.WriteLine(grades.Count); // Prints 5

Stack Count Property extraGrade

//Pop() to remove highest item
Console.WriteLine(grades.Pop()); // Prints E

Stack Pop Method grades

//Using while loop to remove all the items 1 by 1
while (grades.Count > 0)
    Console.WriteLine(grades.Pop());

Console.WriteLine(grades.Count); // Prints 0                

//Reset items
grades = new Stack<char>(extraGrade);
grades.Push('D');
grades.Push('E');

//Clear() to remove all the items
grades.Clear();
Console.WriteLine(grades.Count); // Prints 0

Run Demo

Stack<string> Vegetables = new Stack<string>();
Vegetables.Push("Carrot");
Vegetables.Push("Cucumber");
Vegetables.Push("Tomato");
Vegetables.Push("Onion");
Vegetables.Push("Green Pepper");

Stack<int> integerValues = new Stack<int>(3);
integerValues.Push(1);
integerValues.Push(2);
integerValues.Push(3);

//Code that creates a stack that holds decimal values
Stack<decimal> decimalValues = new Stack<decimal>();
decimalValues.Push(13.2m);
decimalValues.Push(20.74m);
decimalValues.Push(8.34m);

Run Demo

var planets = new Stack<Planet>();
planets.Push(new Planet() { Id = 1, Name = "Mercury" });
planets.Push(new Planet() { Id = 2, Name = "Venus" });
planets.Push(new Planet() { Id = 3, Name = "Earth" });

foreach (var planet in planets)
      Console.WriteLine($"{planet.Id}, {planet.Name}");

class Planet
{
  public int Id { get; set; }
  public string Name { get; set; }
}

Run Demo

Loops

C# Reference | Microsoft Docs