.NET Framework: Collections and Generics

The original release of the .NET Framework
included collections as .NET
was introduced to the Microsoft programming world. The .NET Framework 2.0
introduced generics to complement the System.Collections namespace and provide
a more efficient and well performing option.

Introduction to Collections

A collection is a container to which objects can be added.
This container offers a powerful flexibility and adaptability. Collections
often hold data items that are traversed in a loop structure. All of the items
stored in the collection are stored as objects. This means that whatever type
you are putting in the collection is taken down to its root object form as it
is put in the collection and put back to its native form as it is pulled out.
The act of taking a static instance of a particular class down to its base
object type and back again is referred to as boxing and unboxing. The example
below demonstrates filling an ArrayList, which is a type of collection, and
getting the items back out. Notice how the items have to be cast as they are
retrieved to return them to their native type.

System.Collections.ArrayList testList = new System.Collections.ArrayList();

// Add some numbers to the list
for (int i = 0; i < 20; i++)
{
  // Go ahead and play here.  You can add whatever type you want in here
  // without issue as you add.  Will be an issue for you at runtime as you
  // retrieve items.
  testList.Add(i);
}

foreach (var item in testList)
{
  // Go ahead and try something like item + 1 here without the cast
  // and see what happens!
  Console.Write("{0}", (int)item);
}

C#
introduced the object initialization syntax, which allows you to initialize a
collection with values at the time of declaration. This makes collections
easier to work with, or at least easy to write example code with! The
initializer syntax looks very similar to normal declaration syntax, but adds
curly brackets that surround the data being initialized. The following sample
code demonstrates the syntax.

int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

There is a performance challenge with collections since they
store everything as objects. There is overhead as items are added or removed
from a collection because they are boxed and unboxed to a specific type. An
additional drawback is that you lose compile time type checking to enforce
consistent use of the same type within your collection. There is a workaround
for the type check, which involves creating a wrapper class of your own that
inherits from CollectionBase and limits the specific type that can be added or
removed from the collection. However, if your C# programming is collection
intensive, that increases the amount of code you need to write and maintain.

Generics

Generics were introduced in the version 2.0 of the Microsoft
framework as a solution to the problems with collections mentioned above.
Generics offer a combination of type safety, performance, and generality in the
type. A generic is a type safe class that is declared without a specific type
applied to its definition. The type is specified at the time the object is
actually instantiated and used. The .NET Framework includes a number of generic
objects in the System.Collections.Generic namespace. It is likely you will find
that many of these will meet your needs. In the event they don’t, you can
always build your own generic classes as well. The C# tutorial code below is a
rewrite of our prior example, but using generics this time. You’ll see that you
get the compile time checking as well as the automatic type recognition as you
retrieve.

List testGeneric = new List();
for (int i = 0; i < 20; i++)
{
  // Go ahead and play here.  You'll get a compile time error here
  // if you try to add anything other than an int.
  testGeneric.Add(i);
}

foreach (int item in testGeneric)
{
  Console.Write("{0}", item);
}

Summary

We have looked at the original collection that was
introduced with the .NET Framework. We discussed the challenges in using it,
and introduced Generics which offer a solution to the performance issues and
lack of compile time check with collections. It is likely that most of the
collection types you will use as a .NET developer going forward will be of the
generic variety given the advantages.

More by Author

Must Read