Sunday, November 23, 2008

Collection Classes in .NET 3.5

pencil icon, that"s clickable to start editing the post

Being able to easily handle collections both in terms of functionality and performance is central to any computer language. Going from plain arrays with memory handling i C++ to the STL collection classes was a hurge lap forward. I practice I've used very few variants since much functionality is often handled in the persistens layer. C# and .NET has plenty of built-in collection classes, and it's practical to know and needed for the 70-536 Exam:

Developing applications that use system types and collections (15 percent)

  • Manage a group of associated data in a .NET Framework application by using collections.
    May include but is not limited to: ArrayList class; Collection interfaces; Iterators; Hashtable class; CollectionBase class and ReadOnlyCollectionBase class; DictionaryBase class and DictionaryEntry class; Comparer class; Queue class; SortedList class; BitArray class; Stack class
  • Improve type safety and application performance in a .NET Framework application by using generic collections.
    May include but is not limited to: Collection.Generic interfaces; Generic Dictionary; Generic Comparer class and Generic EqualityComparer class; Generic KeyValuePair structure; Generic List class, Generic List.Enumerator structure, and Generic SortedList class; Generic Queue class and Generic Queue.Enumerator structure; Generic SortedDictionary class; Generic LinkedList; Generic Stack class and Generic Stack.Enumerator structure
  • Manage data in a .NET Framework application by using specialized collections.
    May include but is not limited to: Specialized String classes; Specialized Dictionary; Named collections; CollectionsUtil; BitVector32 structure and BitVector32.Section structure

In this post I'll run through the classes (and save the Interfaces, Base classes and further functionality for another post). First the four relevant namespaces:

System.Collections
The System.Collections namespace contains interfaces and classes that define various collections of objects, such as lists, queues, bit arrays, hash tables and dictionaries.
System.Collections.Generic
The System.Collections.Generic namespace contains interfaces and classes that define generic collections, which allow users to create strongly typed collections that provide better type safety and performance than non-generic strongly typed collections.
System.Collections.ObjectModel
The System.Collections.ObjectModel namespace contains classes that can be used as collections in the object model of a reusable library. Use these classes when properties or methods return collections.
System.Collections.Specialized
The System.Collections.Specialized namespace contains specialized and strongly-typed collections; for example, a linked list dictionary, a bit vector, and collections that contain only strings.

Collection Classes

System.Collections

ArrayList
Implements the IList interface using an array whose size is dynamically increased as required.
BitArray
Manages a compact array of bit values, which are represented as Booleans, where true indicates that the bit is on (1) and false indicates the bit is off (0).
Hashtable
Represents a collection of key/value pairs that are organized based on the hash code of the key.
Queue
Represents a first-in, first-out collection of objects.
SortedList
Represents a collection of key/value pairs that are sorted by the keys and are accessible by key and by index.
Stack
Represents a simple last-in-first-out (LIFO) non-generic collection of objects.

System.Collections.Specialized

HybridDictionary
Implements IDictionary by using a ListDictionary while the collection is small, and then switching to a Hashtable when the collection gets large.
ListDictionary
Implements IDictionary using a singly linked list. Recommended for collections that typically contain 10 items or less.
NameValueCollection
Represents a collection of associated String keys and String values that can be accessed either with the key or with the index.
OrderedDictionary
Represents a collection of key/value pairs that are accessible by the key or index.
StringCollection
Represents a collection of strings.
StringDictionary
Implements a hash table with the key and the value strongly typed to be strings rather than objects.

System.Collections.ObjectModel

ObservableCollection(T)
Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
ReadOnlyObservableCollection(T)
Represents a read-only ObservableCollection(T).

System.Collections.Generic

Dictionary(TKey, TValue)
Represents a collection of keys and values.
HashSet(T)
Represents a set of values.
KeyedByTypeCollection(TItem)
Provides a collection whose items are types that serve as keys.
LinkedList(T)
Represents a doubly linked list.
List(T)
Represents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and manipulate lists.
Queue(T)
Represents a first-in, first-out collection of objects.
SortedDictionary(TKey, TValue)
epresents a collection of key/value pairs that are sorted on the key.
SortedList(TKey, TValue)
Represents a collection of key/value pairs that are sorted by key based on the associated IComparer(T) implementation.
Stack(T)
Represents a variable size last-in-first-out (LIFO) collection of instances of the same arbitrary type.
SynchronizedCollection(T)
Provides a thread-safe collection that contains objects of a type specified by the generic parameter as elements
SynchronizedKeyedCollection(K, T)
Provides a thread-safe collection that contains objects of a type specified by a generic parameter and that are grouped by keys.
SynchronizedReadOnlyCollection(T)
Provides a thread-safe, read-only collection that contains objects of a type specified by the generic parameter as elements.

What should I choose and when?

I am no expert, but I would use on of the generic variants if possible, since I like strong types (type-safe) and I even more hate those pesky casts from Object into a magical and sometimes unknown class. Infact I can't see no reason not to, since if it's bumped together in a collection I expect them to be related at least by an Interface.

In C++ I got away with something like 92% Vectors, 6% Maps and a minority of other collections from STL. In practical C# I'll probably do more or less the same, but for the Exam I'll probably have to learn the more odd ones, not that I mind using a Queue or Stack where it fits. My aversion for linked Lists has probably something to do with it being a little harder to iterate in C++ and this is most definitely much easier in the newer C#/.NET.

I've later found a good resource on Collection Classes (C# Programming Guide) that among other has a reference to the guide: Selecting a Collection Class.