Generic collections in .NET

The .NET class library provides a number of generic collection classes in the System.Collections.Generic and System.Collections.ObjectModel namespaces. For more detailed information about these classes, see Commonly Used Collection Types.


Many of the generic collection types are direct analogs of nongeneric types. Dictionary<TKey,TValue> is a generic version of Hashtable; it uses the generic structure KeyValuePair<TKey,TValue> for enumeration instead of DictionaryEntry.

List<T> is a generic version of ArrayList. There are generic Queue<T> and Stack<T> classes that correspond to the nongeneric versions.

There are generic and nongeneric versions of SortedList<TKey,TValue>. Both versions are hybrids of a dictionary and a list. The SortedDictionary<TKey,TValue> generic class is a pure dictionary and has no nongeneric counterpart.

The LinkedList<T> generic class is a true linked list. It has no nongeneric counterpart.


The Collection<T> generic class provides a base class for deriving your own generic collection types. The ReadOnlyCollection<T> class provides an easy way to produce a read-only collection from any type that implements the IList<T> generic interface. The KeyedCollection<TKey,TItem> generic class provides a way to store objects that contain their own keys.

Other generic types

The Nullable<T> generic structure allows you to use value types as if they could be assigned null. This can be useful when working with database queries, where fields that contain value types can be missing. The generic type parameter can be any value type.


In C# and Visual Basic, it is not necessary to use Nullable<T> explicitly because the language has syntax for nullable types. See Nullable value types (C# reference) and Nullable value types (Visual Basic).

The ArraySegment<T> generic structure provides a way to delimit a range of elements within a one-dimensional, zero-based array of any type. The generic type parameter is the type of the array's elements.

The EventHandler<TEventArgs> generic delegate eliminates the need to declare a delegate type to handle events, if your event follows the event-handling pattern used by .NET. For example, suppose you have created a MyEventArgs class, derived from EventArgs, to hold the data for your event. You can then declare the event as follows:

    event EventHandler<MyEventArgs^>^ MyEvent;
public event EventHandler<MyEventArgs> MyEvent;
Public Event MyEvent As EventHandler(Of MyEventArgs)

See also