Collection types are the common variations of data collections, such as hash tables, queues, stacks, dictionaries, and lists.
Collections are based on the ICollection interface, the IList interface, the IDictionary interface, or their generic counterparts. The IList interface and the IDictionary interface are both derived from the ICollection interface; therefore, all collections are based on the ICollection interface either directly or indirectly.
The KeyedCollection<TKey, TItem> class is unique because it is a list of values with keys embedded within the values and, therefore, it behaves like a list and like a dictionary.
Collections can vary, depending on how the elements are stored, how they are sorted, how searches are performed, and how comparisons are made. The elements of a Dictionary<TKey, TValue> are accessible only by the key of the element, but the elements of a KeyedCollection<TKey, TItem> are accessible either by the key or by the index of the element. The indexes in all collections are zero-based, except Array, which allows arrays that are not zero-based.
The Array class is not part of the System.Collections namespaces. However, it is still a collection because it is based on the IList interface.
The rank of an Array object is the number of dimensions in the Array. An Array can have one or more ranks.
Unlike the classes in the System.Collections namespaces, Array has a fixed capacity. To increase the capacity, you must create a new Array object with the required capacity, copy the elements from the old Array object to the new one, and delete the old Array.
The capacity of an Array is fixed, whereas the capacity of a List<T> is automatically expanded as required. If the value of the Capacity property changes, the memory reallocation and copying of elements occur automatically.
The List<T> class provide methods that add, insert, or remove a range of elements. In Array, you can get or set the value of only one element at a time.
The List<T> provide methods that return read-only and fixed-size wrappers to the collection. The Array class does not.
On the other hand, Array offers some flexibility that List<T> does not. For example:
You can set the lower bound of an Array, but the lower bound of a List<T> is always zero.
An Array can have multiple dimensions, while a List<T> always has exactly one dimension.
Most situations that call for an array can use a List<T> instead; they are easier to use and, in general, have performance similar to an array of the same type.
The Queue<T> and Stack<T> generic classes are useful when you need temporary storage for information, that is, when you might want to discard an element after retrieving its value. Use Queue<T> if you need to access the information in the same order that it is stored in the collection. Use Stack<T> if you need to access the information in reverse order.
Three main operations can be performed on a Queue<T> and its elements:
The Enqueue method adds an element to the end of the queue.
The Dequeue method removes the oldest element from the start of the queue.
The Peek method returns the oldest element from the start of the queue but does not remove it from the queue.