.NET provides a wide variety of built-in data structures in its libraries to suit different application needs. These data structures are available primarily in the System.Collections, System.Collections.Generic, and System.Collections.Concurrent namespaces.
Here’s an overview of the most commonly used data structures in .NET:
1. Non-Generic Collections
Found in the System.Collections namespace, these work with objects, requiring casting and boxing/unboxing.
- ArrayList: A dynamically sized array.
- Use case: When you need an array-like structure that grows automatically.
- Limitation: Type safety is not enforced.
- Hashtable: Key-value pairs stored as objects.
- Use case: Quick lookups when key-value pairs are needed.
- Limitation: Not type-safe.
- Queue: First In, First Out (FIFO) collection.
- Stack: Last In, First Out (LIFO) collection.
- SortedList: Key-value pairs sorted by keys.
2. Generic Collections
Found in the System.Collections.Generic namespace, these are type-safe and perform better than non-generic collections.
- List<T>:
- Dynamic array supporting type safety.
- Example:
List<int> numbers = new List<int>();
- Use case: When you need an array-like structure with dynamic resizing.
- Dictionary<TKey, TValue>:
- Key-value pair collection optimized for fast lookups.
- Example:
Dictionary<string, int> wordCounts = new Dictionary<string, int>();
- Use case: Lookup tables, caches, and mappings.
- SortedDictionary<TKey, TValue>:
- Similar to
Dictionary
, but keeps elements sorted by key. - Use case: When order by keys is required.
- Similar to
- HashSet<T>:
- Stores unique elements without maintaining order.
- Example:
HashSet<int> uniqueNumbers = new HashSet<int>();
- Use case: Eliminate duplicates and perform set operations.
- Queue<T>:
- Generic FIFO collection.
- Example:
Queue<string> messages = new Queue<string>();
- Use case: Message processing or sequential tasks.
- Stack<T>:
- Generic LIFO collection.
- Example:
Stack<int> backtracking = new Stack<int>();
- Use case: Undo functionality or expression evaluation.
- LinkedList<T>:
- Doubly linked list.
- Example:
LinkedList<int> linkedList = new LinkedList<int>();
- Use case: When frequent insertions/deletions are required.
- SortedList<TKey, TValue>:
- Combines features of
List
andDictionary
, sorting by keys. - Use case: Sorted key-value storage.
- Combines features of
3. Concurrent Collections
Found in the System.Collections.Concurrent namespace, these are designed for thread-safe operations.
- ConcurrentDictionary<TKey, TValue>:
- Thread-safe version of
Dictionary
. - Use case: Caches or data shared across multiple threads.
- Thread-safe version of
- ConcurrentQueue<T>:
- Thread-safe FIFO collection.
- Use case: Task queues in multi-threaded applications.
- ConcurrentStack<T>:
- Thread-safe LIFO collection.
- BlockingCollection<T>:
- Provides producer-consumer pattern support.
- Use case: Coordinating producer-consumer pipelines.
- ConcurrentBag<T>:
- Thread-safe unordered collection.
- Use case: When order doesn’t matter, but thread safety is required.
4. Specialized Collections
Found in System.Collections.Specialized namespace, these provide unique functionality.
- NameValueCollection:
- Stores string keys and values, allowing duplicate keys.
- Use case: Headers, query strings.
- OrderedDictionary:
- Maintains key-value pairs in insertion order.
- Use case: Order-sensitive mappings.
- StringCollection:
- Specialized collection for storing strings.
- Use case: String management.
- StringDictionary:
- Hashtable optimized for string keys.
- Use case: String key-value mappings.
5. Immutable Collections
Found in the System.Collections.Immutable namespace, these collections are immutable by design.
- ImmutableArray<T>:
- Fixed-size array that cannot be modified after creation.
- Use case: Safe shared data in multi-threaded applications.
- ImmutableList<T>:
- Immutable version of
List<T>
. - Use case: Scenarios where list modification must be prohibited.
- Immutable version of
- ImmutableDictionary<TKey, TValue>:
- Immutable version of
Dictionary<TKey, TValue>
.
- Immutable version of
- ImmutableHashSet<T>:
- Immutable version of
HashSet<T>
.
- Immutable version of
- ImmutableQueue<T>, ImmutableStack<T>:
- Immutable FIFO and LIFO collections.
6. Arrays
- Array:
- Fixed-size collection.
- Use case: Known size collections with fast indexing.
- Multi-dimensional Arrays:
- Example:
int[,] grid = new int[3, 3];
- Use case: Representing matrices or grids.
- Example:
- Jagged Arrays:
- Array of arrays.
- Example:
int[][] jagged = new int[3][];
Choosing the Right Data Structure
When selecting a data structure, consider:
- Type of Data: Key-value pairs, unique items, sequential access, etc.
- Performance Needs: Speed of insertions, lookups, deletions, etc.
- Thread Safety: Use concurrent collections for multi-threaded environments.
- Immutability: For thread-safe, read-only scenarios.
Each of these .NET data structures caters to specific use cases, making it easier to develop efficient and maintainable applications
*AI generated