Cover image source
Collections
C# collections have plenty of options to use. When it comes to simple scenarios and small data handling any of these would work fine or at least give you the desired results. Things start to get messy when you have complex scenarios like multi-threading, huge chunks of data, indexing on collections, searching etc.
The Microsoft documentation on collections is a decent place to get started. One of the key things to note from this documentation is:
There are two main types of collections; generic collections and non-generic collections. Generic collections are type-safe at compile time. Because of this, generic collections typically offer better performance. Generic collections accept a type parameter when they are constructed and do not require that you cast to and from the Object type when you add or remove items from the collection.
This means that, in general, a generic collection should be used. The non generic collections will be stored as Object. This means that they will need casting when you are playing around with data. IMHO, I think this will play a very imp role when it comes to performance.
The MSDN link I added before has an excellent piece of advice that will help us in understanding which collection is to be chosen based on our requirement.
Collection | Generic Option | Non-generic Option | Thread-safe or immutable collection options |
---|---|---|---|
Store items as key/value pairs for quick look-up by key | Dictionary<TKey,TValue> |
Hashtable |
ConcurrentDictionary<TKey,TValue> , ReadOnlyDictionary<TKey,TValue> , ImmutableDictionary<TKey,TValue>
|
Access items by index | List<T> |
Array , ArrayList
|
ImmutableList<T> , ImmutableArray
|
Use items first-in-first-out (FIFO) | Queue<T> |
Queue |
ConcurrentQueue<T> , ImmutableQueue<T>
|
Use data Last-In-First-Out (LIFO) | Stack<T> |
Stack |
ConcurrentStack<T> , ImmutableStack<T>
|
Access items sequentially | LinkedList<T> |
No recommendation |
No recommendation |
Receive notifications when items are removed or added to the collection. (implements INotifyPropertyChanged and INotifyCollectionChanged ) |
ObservableCollection<T> |
No recommendation |
No recommendation |
A sorted collection | SortedList<TKey,TValue> |
SortedList |
ImmutableSortedDictionary<TKey,TValue> , ImmutableSortedSet<T>
|
A set for mathematical functions |
HashSet<T> ,SortedSet<T>
|
No recommendation |
ImmutableHashSet<T> , ImmutableSortedSet<T>
|
Another important point that can act as a deciding factor is Algorithmic complexity of collections. Before you chose a collection, it is really important that the complexities are taken into account. This can sort out a lot of issues with respect to time complexities before hand.
In addition to this, David Fowler tweeted excellent points on Hashtable, Dictionary, ConcurrentDictionary, ImmutableDictionary
David Fowler π§π§πΊπΈππ@davidfowl.NET has 4 built-in dictionary/map types:
- Hashtable
- Dictionary
- ConcurrentDictionary
- ImmutableDictionary
Thereβs no guidance on when to use what, mostly individual documentation on each implementation.
#dotnet01:02 AM - 03 Oct 2021
-
Dictionary
-
HashTable, ImmutableDictionary
David Fowler π§π§πΊπΈππ@davidfowlHastable - Good read speed (no lock required), sameish weight as dictionary but more expensive to mutate and no generics!
ImmutableDictionary - Poorish read speed, no locking required but more allocations require to update than a dictionary.01:02 AM - 03 Oct 2021 -
ConcurrentDictionary
The motivation for all of this to put into once place, to keep things handy, came when I was working on one of the scenarios to select a collection. I ran into Scott Hanselman's blog, where he added a few pointers from David's tweet.
I would keep this handy for the next time I have to work on collections.
Top comments (0)