MSDN .NET Framework Documentation

Overview of .NET Collections

The .NET Framework provides a rich set of classes for working with collections of objects. Collections are fundamental data structures that allow you to store, retrieve, and manipulate groups of data efficiently. Whether you need to store a simple list of items, a key-value pair mapping, or a more complex data structure, the .NET Framework offers a solution.

The primary namespace for collection classes is System.Collections and its generic counterpart System.Collections.Generic. Understanding these namespaces and the types they contain is crucial for effective .NET development.

Key Concepts

  • Generics: Introduced in .NET Framework 2.0, generic collections provide type safety and improved performance by allowing you to specify the type of elements the collection can hold.
  • Interfaces: The collection classes implement various interfaces (e.g., IEnumerable, ICollection, IList, IDictionary) that define common behaviors and operations.
  • Type Safety: Generic collections eliminate the need for casting, reducing the risk of runtime errors.
  • Performance: Different collection types are optimized for different operations (e.g., insertion, deletion, lookup), allowing you to choose the most efficient structure for your use case.
What are Collections For?

Collections are used to group related objects. Common scenarios include:

  • Storing a list of user names.
  • Managing a cache of data.
  • Implementing queues, stacks, or lookup tables.
  • Processing large datasets.

Core Collection Interfaces

The foundation of .NET collections lies in a set of interfaces that define their behavior:

  • IEnumerable / IEnumerable<T>: Allows iteration over a collection.
  • ICollection / ICollection<T>: Extends IEnumerable and adds methods for common operations like counting elements, adding, and removing.
  • IList / IList<T>: Represents an ordered collection that can be accessed by index.
  • IDictionary / IDictionary<TKey, TValue>: Represents a collection of key/value pairs, where each key is unique.

Generic Collections (System.Collections.Generic)

Generic collections offer type safety and better performance. The most commonly used generic collections include:

  • List<T>: A resizable array. Ideal for most general-purpose list needs.
  • Dictionary<TKey, TValue>: A hash table implementation. Provides fast lookups by key.
  • HashSet<T>: A set implementation. Stores unique elements and offers fast add, remove, and contains operations.
  • Queue<T>: A first-in, first-out (FIFO) collection.
  • Stack<T>: A last-in, first-out (LIFO) collection.
  • LinkedList<T>: A doubly linked list. Efficient for insertions and deletions anywhere in the list.
Recommendation: Always prefer generic collections over non-generic ones when possible, as they offer type safety and performance benefits.

Non-Generic Collections (System.Collections)

These collections were available in earlier versions of the .NET Framework and do not provide type safety. They are generally used when compatibility with older code is required or when dealing with collections of object.

  • ArrayList: Similar to List<T> but stores elements as object. Requires casting and can lead to boxing/unboxing overhead.
  • Hashtable: Similar to Dictionary<TKey, TValue> but stores keys and values as object.
  • Queue: Non-generic version of Queue<T>.
  • Stack: Non-generic version of Stack<T>.
  • SortedList: A collection that maintains elements in sorted order by key.

Performance Considerations

Choosing the correct collection type can significantly impact your application's performance. Consider the following:

  • Lookup Speed: For fast key-based lookups, Dictionary<TKey, TValue> is generally the best choice (O(1) average time complexity).
  • Insertion/Deletion: List<T> is efficient for adding/removing at the end. For insertions/deletions in the middle, LinkedList<T> can be more performant.
  • Memory Usage: Some collections have higher memory overhead than others.
  • Thread Safety: Standard collections are generally not thread-safe. For concurrent scenarios, consider using thread-safe collections from System.Collections.Concurrent or implementing your own locking mechanisms.

Choosing the Right Collection

To select the appropriate collection, ask yourself:

  • Do I need to store elements of a specific type? (Use generic collections).
  • Do I need to access elements by index? (Use List<T> or IList<T>).
  • Do I need fast lookups based on a unique identifier? (Use Dictionary<TKey, TValue>).
  • Do I need to store only unique elements? (Use HashSet<T>).
  • Do I need a FIFO or LIFO structure? (Use Queue<T> or Stack<T>).
  • Are insertions/deletions in the middle of the collection frequent? (Consider LinkedList<T>).
  • Is thread safety a requirement? (Explore System.Collections.Concurrent).

Mastering the .NET collection classes is fundamental to writing efficient and robust C# applications. Explore the detailed documentation for each collection type to understand its specific capabilities and performance characteristics.