C# Collections

1. Generic

1.1 List<T>

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<TKey, TValue>

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<T>

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

2. Sorted

2.1 SortedSet<T>

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<TKey, TValue>

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<TKey, TValue>

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

3. Concurrent

3.1 ConcurrentQueue<T>

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<T>

ConcurrentQueue but in first-in last-out pattern.

3.3 ConcurrentDictionary<TKey, TValue>

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<T>

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.

posted @ 2019-10-12 16:30  TXRock  阅读(166)  评论(0编辑  收藏  举报