.NET base class libraries ship with a number of namespaces containing collection classes.
Some particular kinds of classes that come pre-built by the .NET Framework are C# collection classes. Like an array, a collection can store more than one value. Unlike arrays, collections don’t have a fixed size. Instead, these classes are built to dynamically resize themselves as you insert or remove elements. In other words, collections are mutable. As a result, collections are usually more appropriate and are highly optimized to manage and organize large amounts of in-memory data very efficiently with the added support of type safety and performance.
There are two categories of collection-related classes and interfaces: those that support generics and those that don’t.
According to Microsoft Docs
Avoid using the types in the System.Collections namespace unless you are specifically targeting .NET Framework version 1.1. The generic and concurrent versions of the collections are to be preferred because of their greater type safety and other improvements.
Prior to .NET 2.0, programmers frequently used the non-generic collection classes found within the System.Collections namespace. These collection classes in the .NET Framework could store different types of objects in the same collection resulting in an error that won’t be discovered until you run the application. Collections created from these classes are sometimes referred to as untyped collections.
Note: non-generic types store object references, and you are required to perform the appropriate casts when you store and retrieve items.
Starting with .NET 2.0 introduced a feature known as generics to allow you to create typed collections. With a typed collection, simply write the data type between the angle brackets < > after the name of the collection class during declaration. Then, you can automatically store and retrieve items using the correct data type in that collection, and any errors will be discovered when you attempt to compile the application. Generic collection classes are located in the System.Collections.Generic namespace.
It is important to point out that you should use strongly typed collection classes that support generics when building a new solution. However, you may need to use non-generic collections for backward compatibility when working with legacy applications. Everything that was available in the non-generic has a generic counterpart that is strongly typed.
Useful types of System.Collections.Generic
|.NET 2.0 to 4.6||.NET 1.x|
|List<T>||ArrayList||A list of objects that can be accessed by index, as with an array, but with additional methods with which to search the list and sort the contents of the list. This is a dynamically resizable sequential list of items.|
|Queue<T>||Queue||A first-in, first-out (FIFO) data structure, with methods to add an item to one end of the queue, remove an item from the other end, and examine an item without removing it.|
|Stack<T>||Stack||A first-in, last-out (LIFO) data structure with methods to push an item onto the top of the stack, pop an item from the top of the stack and examine the item at the top of the stack without removing it.|
|LinkedList<T>||A double-ended ordered list, optimized to support insertion and removal at either end. This collection can act like a queue or a stack, but it also supports random access as a list does.|
|HashSet<T>||An unordered set of values that is optimized for fast retrieval of data. It provides set-oriented methods for determining whether the items it holds are a subset of those in another HashSet<T> object as well as computing the intersection and union of HashSet<T> objects.|
|Dictionary<TKey, TValue>||Hashtable||A collection of values that can be identified and retrieved by using keys rather than indexes.|
|SortedList<TKey, TValue>||SortedList||A sorted list of key/value pairs. The keys must implement the IComparable<T> interface.|