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):
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:
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.
Represents a collection of key/value pairs that are organized based on the key.
Represents the collection of keys in a Dictionary<K, V>.
Represents the collection of values in a Dictionary<K, V>.
Represents a collection that can be iterated using foreach.
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.
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;
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
// Inserting a value
myNumbers.Insert(myNumbers.Count - 3, 0);
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>:
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. :)