C# Collections
阅读原文时间:2023年08月15日阅读:1

1.1 List

No need to say this is the most commonly used data structure in C# collections. Where this collection maintains the order of the added items, therefore indexable. Also easy to query and add/update/remove items. Though it is not thread-safe and requires lock when manipulated across different threads.

1.2 Dictionary

Another commonly used data structure. Where gives an unordered set of KeyValuePair. Allow the user to access values through specific keys. Also provides ValueCollection on Keys and Values which both are enumerable.

1.3 HashSet

Without the need to enumerate or filter. Working with specific methods of sets to union or intersect values. Locate a value more efficient.

2.1 SortedSet

This data structure gives a collection the ability to maintain in sorted order based on an IComparer. Also provides an additional set of features for the user to play with, such as subsets and intersect/unions.

2.2 OrderedDictionary

This data structure keeps the KeyValuePair items of the dictionary in the order they were added. Which is similar to List\<T\> when keeping the order of the added items, and indexable.

2.3 SortedDictionary

While SortedList and SortedList is similar, this data structure is sorted by TKey's value in general.

3.1 ConcurrentQueue

Ordered set of items that is thread-safe. Provides the basic ability to add/update/remove/enumerate, put can only add/remove in a first-in first-out fashion. Which gives a certain degree of limitation for users whom are used to Lists and Dictionaries.

3.2 ConcurrentStack

ConcurrentQueue but in first-in last-out pattern.

3.3 ConcurrentDictionary

Thread-safe dictionaries, hands off one of the best data structures. Also provides an additional set of features for the user to play with, such as AddOrUpdate/GetOrAdd in database style, and TryUpdate/TryRemove which really is trying since they can be called over multiple threads. But to be aware that the data structure itself as an KeyPair Enumerable does not provide enumeration thread-safety, i.e. extension method `Where` would not be thread-safe. Whereas with applying locks, `ToArray()` and `Values` are safe due to their custom implementations within ConcurrentDictionary. Therefore when calling `ToArray().Where` or `Values.Where`, snapshots are provided before enumeration, so while enumerating through the collection, new item adds or removes does not apply to the current enumeration.

Take a look at: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs

3.4 BlockingCollection

The magic behind IProducerConsumerCollection which is used through all concurrent collections. GetConsumingEnumerable blocks the enumeration if there are no items in the collection, and continues to consume, or we can call it take(get and remove an item from the queue first-in first-out), from the enumeration once a new item is added(published) to the collection. Only when a cancellation token is requested or CompleteAdding is called, does the enumeration breaks and ends consuming.