
What Are Collection Classes?
Arrays are useful, but they have their limitations. However, arrays are only one way to
collect elements of the same type. The.NET Framework provides several classes that also
collect elements together in other specialized ways. These are the Collection classes, and
they live in the System.Collections namespace and sub-namespaces.
The basic collection classes accept, hold, and return their elements as objects. That is, the
element type of a collection class is an object. To understand the implications of this, it is
helpful to contrast an array of int variables (int is a value type) with an array of objects
(object is a reference type). Because int is a value type, an array of int variables holds its
int values directly, as shown in the following graphic:
Now consider the effect when the array is an array of objects. You can still add integer
values to this array (in fact, you can add values of any type to it). When you add an
integer value, it is automatically boxed and the array element (an object reference) refers
to the boxed copy of the integer value. (For a refresher on boxing, refer to Chapter 8.)
This is illustrated in the following graphic:
Remember that the element type of a collection class is an object. This means that when
you insert a value into a collection, it is always boxed, and when you remove a value
from a collection, you must unbox it by using a cast. The following sections provide a
very quick overview of four of the most useful Collection classes. Refer to the .NET
Framework documentation for more details on each class.
NOTE
In fact, there are Collection classes that don't always use object as their element type and
that can hold value types as well as references, but you need to know a bit more about C#
before we can talk about them. You will meet these Collection classes in Chapter 17,
“Introducing Generics.”
The ArrayList Class
ArrayList is a useful class for shuffling elements around in an array. There are certain
occasions when an ordinary array can be too restrictive:

• If you want to resize an array, you have to create a new array, copy the elements
(leaving out some if the new array is smaller), and then update the array
references.
• If you want to remove an element from an array, you have to make a copy of the
element and then move all the trailing elements up by one place. Even this doesn't
quite work because you end up with two copies of the last element.
• If you want to insert an element into an array, you have to move elements down by
one place to make a free slot. However, you lose the last element of the array!
Here's how you can overcome these restrictions by using the ArrayList class:
• You can remove an element from an ArrayList by using its Remove method. The
ArrayList automatically reorders its elements.
NOTE
You cannot use the Remove method in a foreach loop that iterates through an
ArrayList.
• You can add an element to the end of an ArrayList by using its Add method. You
supply the element to be added. The ArrayList resizes itself if necessary.
• You can insert an element into the middle of an ArrayList by using its Insert
method. Again, the ArrayList resizes itself if necessary.
Here's an example that shows how you can create, manipulate, and iterate through the
contents of an ArrayList:
using System;
using System.Collections;
...
ArrayList numbers = new ArrayList();
...
// fill the ArrayList
foreach (int number in new int[12]{10,9,8,7,7,6,5,10,4,3,2,1})
{
numbers.Add(number);
}
...
// remove first element whose value is 7 (the 4th element, index 3)
numbers.Remove(7);
// remove the element that's now the 7th element, index 6 (10)
numbers.RemoveAt(6);
...
// iterate remaining 10 elements using a for statement

for (int i = 0; i != numbers.Count; i++)
{
int number = (int)numbers[i]; // Notice the cast
Console.WriteLine(number);
}
...
// iterate remaining 10 using a foreach statement
foreach (int number in numbers) // No cast needed
{
Console.WriteLine(number);
}
The output of this code is shown below:
10
9
8
7
6
5
4
3
2
1
10
9
8
7
6
5
4
3
2
1
NOTE
You use the Count property to find out how many elements are inside a collection. This is
different from arrays, which use the Length property.
The Queue Class
The Queue class implements a first-in first-out (FIFO) mechanism. An element is
inserted into the queue at the back (the enqueue operation) and is removed from the
queue at the front (the dequeue operation).

Here's an example of a queue and its operations:
using System;
using System.Collections;
...
Queue numbers = new Queue();
...
// fill the queue
foreach (int number in new int[4]{9, 3, 7, 2})
{
numbers.Enqueue(number);
Console.WriteLine(number + " has joined the queue");
}
...
// iterate through the queue
foreach (int number in numbers)
{
Console.WriteLine(number);
}
...
// empty the queue
while (numbers.Count != 0)
{
int number = (int)numbers.Dequeue();
Console.WriteLine(number + " has left the queue");
}
The output from this code is:
9 has joined the queue
3 has joined the queue
7 has joined the queue
2 has joined the queue
9
3
7
2
9 has left the queue
3 has left the queue
7 has left the queue
2 has left the queue
The Stack Class

The Stack class implements a last-in first-out (LIFO) mechanism. An element joins the
stack at the top (the push operation) and leaves the stack at the top (the pop operation).
To visualize this, think of a stack of dishes: new dishes are added to the top and dishes
are removed from the top, making the last dish to be placed onto the stack the first one to
be removed (the dish at the bottom is rarely used, and will inevitably require washing
before you can put any food on it as it will be covered in grime!). Here's an example:
using System;
using System.Collections;
...
Stack numbers = new Stack();
...
// fill the stack
foreach (int number in new int[4]{9, 3, 7, 2})
{
numbers.Push(number);
Console.WriteLine(number + " has been pushed on the stack");
}
...
// iterate through the stack
foreach (int number in numbers)
{
Console.WriteLine(number);
}
...
// empty the stack
while (numbers.Count != 0)
{
int number = (int)numbers.Pop();
Console.WriteLine(number + "has been popped off the stack");
}
The output from this program is:
9 has been pushed on the stack
3 has been pushed on the stack
7 has been pushed on the stack
2 has been pushed on the stack
2
7
3
9
2 has been popped off the stack