Generic Collections I

In one of my first posts I briefly mentioned that I would discuss a bit about what I’ve learned about using the new generic collections.  I’ve been putting it off a bit because I knew it would be a bit lengthy, but I really feel this is important so I’m going to push myself to start making the effort. 😉  Here’s what I plan to cover (in relation to generic collections):

  • Advantages of generic collections
  • Predicates & other System delegate types
  • Anonymous delegates
  • Subclassing generic collections
  • Other resources (including Power Collections)

I’m not going to go over generics.  If you want details on generics here are a few links:

I also won’t go over anonymous delegates in detail.  You can find some useful information here:



Generic collections are the generic equivalents (I like to think of them as replacements) for the System.Collections classes.  They are found in the System.Collections.Generic space.

Generic collections have a number of advantages over the old collections.  Chief among them are:

  • They are type safe.
  • Better performance.  (no boxing/unboxing!)
  • Richer functionality through System defined delegate types.

To top it off they are quite compatible with the old collections and methods that use them.  Both ArrayList and List<T>  support IList, ICollection, IEnumerable, and ICloneable for example.  If existing methods use the old interfaces for parameters there is nothing extra you have to do to start using the generic collections.   (Hey, look! A great reason to take the interface (IList) as a parameter instead of the collection class (ArrayList).)  Converting is easy beyond this as the old collections take ICollection or IDictionary as a constructor parameter.

Here’s a quick overview of how the new collections map to old ones (from: Generics in the .NET Framework Class Library (C# Programmers Reference))

Generic Class or Interface


Corresponding Non-Generic Type



Provides the base class for a generic collection.






Compares two objects of the same generic type for equivalence and for sorting.




Dictionary<K, V>


Represents a collection of key/value pairs that are organized based on the key.



Dictionary<K, V>.KeyCollection

Represents the collection of keys in a Dictionary<K, V>.


Dictionary<K, V>.ValueCollection

Represents the collection of values in a Dictionary<K, V>.




Represents a collection that can be iterated using foreach.



KeyedCollection<T, U>

Represents a keyed collection.



Represents a doubly linked list.



Represents a node in a LinkedList<T>.




Implements the IList<T> interface using an array whose size is dynamically increased as required.




Represents a first-in, first-out collection of objects.



Provides the base class for a generic read-only collection.


SortedList<K, V>

Represents a collection of key/value pairs that are sorted by key based on the associated IComparer<T> implementation.



Represents a simple last-in-first-out (LIFO) collection of objects.



First Look at a Generic Collection Class

The best place to start is to look at the workhorse of the generic collection family, the generic List class, or List<T>.  List<T> is meant to replace the functionality of ArrayList.  It is a simple ordered collection of objects of type <T>.  You can think of it as a wrapped array because that’s precisely what it is–internally data is stored as private T[] _items;

As with any array, appending is usually fast (unless the array is being resized) and insertion gets proportionally slower as the number of elements grows.  I’ve already mentioned that it supports IList, ICollection, and IEnumerable.  It also supports the generic equivalents IList<T>, ICollection<T>, and IEnumerable<T>.

Lets take a look at some simple usage of List<T>, shall we?  (Finally, some code!)

// Creating a List<T> (Also has constructors that take a collection or specify the initial size)
List<int> myNumbers = new List<int>();

// Adding a value

// Adding a range of values
myNumbers.AddRange(new int[]{1,2,3});

// Inserting a value
myNumbers.Insert(myNumbers.Count – 3, 0);

// Iterating
foreach (int number in myNumbers)
   // Output is 42, 0, 1, 2, 3

The code above should be pretty self explanatory.  Here is a summary of the functionality that is available to you in List<T>:

  • Add or insert objects of collections of type T
  • Removal

    • Remove, RemoveAt, RemoveRange, RemoveAll

  • Sorting

    • Sort (Comparison<T>)
    • Reverse

  • Conversion

    • ConvertAll (Converter<T,U>)
    • CopyTo(T[])

  • Searching (Predicate<T>)

    • Exists
    • Find, FindAll, FindLast
    • FindIndex, FindLastIndex, IndexOf, LastIndexOf
    • TrueForAll

  • Iterating

    • ForEach (Action<T>)

In bold you will see that I’ve called out the System delegate types.  They are the key to unlocking super rich functionality within these classes.  This makes a nice transition to my next blog entry where I’ll start by taking a look at Predicate<T> and then this discussion will get really interesting. 🙂

Comments (10)

  1. In yesterday’s post I went over the very basics of generic collections in the 2.0 .Net framework.&amp;nbsp;…

  2. esteewhy says:

    Jeremy, could you please also tell some more about Dictionary<K, V>.KeyCollection ? (Oh, of coruse if you still care about such matters 😉 ..

    Is it intended to index generic collection’s keys/values by integer ? ‘t seems msdn2 doesn’t help much ..

    thank you

  3. jkuhne says:

    KeyCollections are passed back by the .Keys property.  I use them (and .Values) in a few places to easily iterate through the keys (or values) that are in use.  I’ll see if I can’t write up some examples in the future.

  4. In C# 2.0, generics and generic collections are notable and very useful features to pay attention to:

  5. In yesterday’s post I went over the very basics of generic collections in the 2.0 .Net framework. Today