In C#, collections are used to store and manage groups of objects. These collections can be broadly categorized into two types: generic collections and non-generic collections.
Non-Generic Collections (legacy collections):
Non-generic collections have been available in C# since earlier versions of the language. They are not type-safe and typically store objects of the
System.Object
type (object
). The main non-generic collection classes include:ArrayList: An ArrayList is a dynamic array that can store objects of any type. It's not type-safe, meaning it allows you to store objects of any class.
HashTable: A HashTable stores key-value pairs. Keys and values can be of any type, but it's not type-safe.
SortedList: A SortedList stores key-value pairs in sorted order. Like HashTable, it's not type-safe.
Stack: A Stack represents a last-in, first-out (LIFO) collection of objects.
Queue: A Queue represents a first-in, first-out (FIFO) collection of objects.
Non-generic collections lack type safety, which can lead to runtime errors if you attempt to access objects with the wrong data types.
Example of using a non-generic ArrayList:
ArrayList list = new ArrayList(); list.Add(42); list.Add("Hello"); int number = (int)list[0]; // Runtime error if the element is not an int
Generic Collections:
Generic collections were introduced in C# 2.0 and provide type safety by allowing you to specify the type of elements they can store when you declare them. The main generic collection classes are part of the
System.Collections.Generic
namespace and include:List\
: A dynamic array that stores a list of elements of a specific type T
.Dictionary\
: A collection of key-value pairs, where the keys and values are of specific types TKey
andTValue
.HashSet\
: A set of unique elements of type T
.Queue\
: A first-in, first-out (FIFO) collection of elements of type T
.Stack\
: A last-in, first-out (LIFO) collection of elements of type T
.
Generic collections offer type safety, improved performance, and better code readability. Here's an example of using a generic List:
List<int> numbers = new List<int>(); numbers.Add(42); int number = numbers[0]; // No casting required, and type is known at compile-time.
In general, it's recommended to use generic collections whenever possible because they provide better type safety and improved performance. Non-generic collections are considered legacy and are less commonly used in modern C# code unless you have specific compatibility requirements with older codebases.