Using Lists and Stacks in .NET

Hands up. How many of you use 'List<T>' on a regular basis?

If the core software you write consists mostly of lines of business apps, then I'm sure like me, quite a lot of you do. But, did you ever stop to thoroughly explore some of the more esoteric types that are available in the .NET collections namespace?

It might surprise some that, as well as the more commonly known dictionary and array types, .NET has quite a few classes designed for implementing things like FIFO/LIFO Queues, linked lists, and many other structures that you might never have even realised.

Interesting, but if I've Gotten This Far Without Needing Them...

Many will proclaim that if they've gotten this far in their career without knowing about the existence of these extra types, why suddenly start using them?

Like many tools in the developers' toolbox, it's not about suddenly starting to use them, but more a realisation that you now have an extra tool, and you never know when it's going to come in handy. This is exactly what happened to me, and why it prompted me to write this post about the hidden gems available.

On a recent project, I had to research a different way of managing a collection of data in an application I was maintaining. This data, due to its structure, warranted a slight deviation from the norm. As a result, I ended up uncovering some of the collection types I describe below.

Bit Array

The Bit Array class is, in the true sense of the word, just like a normal Array. Under the hood, however, it harbours some very clever tricks.

The idea behind the Bit Array is to store a collection of ones and zeros, represented in individual units as Boolean true/false values. Behind the scenes, however, everything is packed down into bytes/ints as far as possible. This means you can—at least in theory—pack 32 bits of information into the same space that a one-element integer array would occupy.

Bit Arrays can be constructed from byte arrays; so, for example, if you did the following:

byte[] myBytes = new byte[5] { 255, 255 };
BitArray myBA3 = new BitArray( myBytes );

You would end up with a Bit Array containing 16 Boolean elements all set to true.

The actual bit pattern set is derived from the bit pattern produced. If you were to turn the individual values into their binar, representations. This is useful for things like compression systems, or taking parallel data and streaming it serially, perhaps down a serial cable, or in a serial network simulation.

You also can take two Bit Arrays and perform useful operations on them, such as 'AND', 'OR', and 'XOR'. This will allow you to perform bit-level operations without having to resort to individual bit twiddling.


Queues are used to create FIFO (first in first out) structures. This kind of structure is very useful for sequentially processing a set of messages or commands. For example, if you had an internal message bus in your application, you could use the queue to receive the messages coming in from the bus, and make them ready for a processor to use them.

Unlike a normal list, you don't reference items in the queue directly by an index. You add items to the queue by using the following statements:

Queue myQueue = new Queue();
myQueue.Enqueue("Message 1");
myQueue.Enqueue("Message 2");
myQueue.Enqueue("Message 3");

This will add the three messages such that the last one added will be the last one out.

You get the value at the head by using the reverse of the 'Enqueue' method 'Dequeue', as follows:

string msg1 = myQueue.Dequeue();

you can use the 'Peek' method to check if there is anything present without removing it, and like all the classes in the namespace, the queue presents an IEnumerable iteration interface so you can do things such as 'for each' over the collection.


Stacks are the opposite of a queue and are used to construct a LIFO (last in first out) structure. The easiest way to picture this is to imagine a stack of plates.

As you put one plate on top of another, the stack grows higher. When you need a plate, you take one from the top of the stack. The last plate added to the stack was the next one out. Stacks are often used for temporary lists of things like parameters while a calculation is performed on them. In fact, some mathematical operations performed using methods, such as reverse polish notation, are inherently based around the concept of a stack.

To add items to a stack, use the 'Push' method. To get the value at the top of the stack, use 'Pop' (to pop off the top value) as follows:

Stack myStack = new Stack();
myStack.Push("Message 1");
myStack.Push("Message 2");
myStack.Push("Message 3");

string msg3 = myStack.Pop();

There are others too, such as an ArrayList, SortedList, and a ReadOnlyCollection. However, the one big thing that many may not realise has been added to the collection's name space are the parallel tasking extensions. Along with the addition of the collections in the PLinq (Parallel Linq) namespaces, most of the structures in the standard system.collections namespace have now been extended to include operations such as 'AsParallel'.

What this means is that, when performing Linq queries using these collections, you can apply AsParallel to allow the query to do multiple operations on multiple threads making best use of multi core machines. As well as these extensions, there are a number of interface types, allowing you to build custom data types easily, while using the underlying existing structures to avoid having to re-invent the wheel.

If you want to explore the namespace further, the main MSDN page for it can be found at

If there's anything you'd like to see covered in this column, please feel free to hunt me down on Twitter where I can be found as @shawty_ds. I also help run a small .NET users group on the Linked-in network, called Lidnug. Please feel free to swing by and say hello, and I'll see what I can do to get your topic included in this column.

Related Articles


  • Mr

    Posted by Gavin on 09/08/2014 12:40am

    Very nice refresh on that topic. I've personally not come across a reason to use a stack yet, but the Queue has soon some use for some front end scenarios. Nice to be reminded the others are there.

    • RE: Mr

      Posted by Peter Shaw on 09/26/2014 07:45am

      Hi Gavin, Glad to hear it was useful to you, please do share your success stories to, I'm always interested in hearing the creative uses developers put these tools to.

  • MD

    Posted by Jim Reid on 09/01/2014 03:39am

    In the Bit Array example: byte[] myBytes = new byte[5] { 255, 255 }; BitArray myBA3 = new BitArray( myBytes ); (1): Shouldn't the first line read: byte[] myBytes = new byte[2] { 255, 255 }; The remaining 3 Bytes seem to be redundant. (2): I not sure why the variable name myBA3 has been so chosen. Did you mean myBA2 ? Sorry if I have misunderstood the example, but, if so, I would still be grateful for an explanation. Many thanks Jim Reid

    • RE: MD

      Posted by Peter Shaw on 09/26/2014 07:49am

      Hi Jim, Well spotted, yes that should indeed be only 2 bytes. I think maybe my caffeine level may have been a little low when I typed that. :-) As for BA3, well not quite sure why 'BA3' but the BA was supposed to be short form of 'BitArray' there's a good chance that was a caffine affected type too. Come find me on twitter - @shawty_ds I'll see if I can rustle you up a freebie for something dev related for spotting that one :-) Shawty

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date