Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

.NET Generics 4.0: Container Patterns and Best Practices

Save for later
  • 360 min read
  • 2012-01-24 00:00:00

article-image

(For more resources on .NET, see here.)


Generic container patterns


There are several generic containers such as List<T>, Dictionary<Tkey,Tvalue>, and so on. Now, let's take a look at some of the patterns involving these generic containers that show up more often in code.

How these are organized


Each pattern discussed in this article has a few sections. First is the title. This is written against the pattern sequence number. For example, the title for Pattern 1 is One-to-one mapping. The Pattern interface section denotes the interface implementation of the pattern. So anything that conforms to that interface is a concrete implementation of that pattern. For example, Dictionary<TKey,TValue> is a concrete implementation of IDictionary<TKey,TValue>. The Example usages section shows some implementations where TKey and TValue are replaced with real data types such as string or int. The last section, as the name suggests, showcases some ideas where this pattern can be used.

Pattern 1: One-to-one mapping


One-to-one mapping maps one element to another.

Pattern interface


The following is an interface implementation of this pattern:
IDictionary<TKey,Tvalue>

Some concrete implementations


Some concrete implementations of this pattern are as follows:

  • Dictionary<TKey,TValue>
  • SortedDictionary<TKey,TValue>
  • SortedList<TKey,TValue>

Example usages


The following are examples where TKey and TValue are replaced with real data types such as string or int:

  • Dictionary<string,int>
  • SortedDictionary<int,string>
  • SortedList<string,string>
  • Dictionary<string,IClass>

Some situations where this pattern can be used


One-to-one mapping can be used in the following situations:

  • Mapping some class objects with a string ID
  • Converting an enum to a string
  • General conversion between types
  • Find and replace algorithms where the find and replace strings become key and value pairs
  • Implementing a state machine where each state has a description, which becomes the key, and the concrete implementation of the IState interface becomes the value of a structure such as Dictionary<string,IState>

Pattern 2: One-to-many unique value mapping


One-to-many unique value mapping maps one element to a set of unique values.

Pattern interface


The following is an interface implementation of this pattern:
IDictionary<TKey,ISet<Tvalue>>

Some concrete implementations


Some concrete implementations of this pattern are as follows:

  • Dictionary<TKey,HashSet<TValue>>
  • SortedDictionary<TKey,HashSet<TValue>>
  • SortedList<TKey,SortedSet<TValue>>
  • Dictionary<TKey,SortedSet<TValue>>

Example usages


The following are examples where TKey and TValue are replaced with real data types such as string or int:

  • Dictionary<int,HashSet<string>>
  • SortedDictionary<string,HashSet<int>>
  • Dictionary<string,SortedSet<int>>

Some situations where this pattern can be used


One-to-many unique value mapping can be used in the following situations:

  • Mapping all the anagrams of a given word
  • Unlock access to the largest independent learning library in Tech for FREE!
    Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
    Renews at $15.99/month. Cancel anytime
  • Creating spell check where all spelling mistakes can be pre-calculated and stored as unique values

Pattern 3: One-to-many value mapping


One-to-many value mapping maps an element to a list of values. This might contain duplicates.

Pattern interface


The following are the interface implementations of this pattern:

  • IDictionary<TKey,ICollection<Tvalue>>
  • IDictionary<TKey,Ilist<TValue>>

Some concrete implementations


Some concrete implementations of this pattern are as follows:

  • Dictionary<TKey,List<TValue>>
  • SortedDictionary<TKey,Queue<TValue>>
  • SortedList<TKey,Stack<TValue>>
  • Dictionary<TKey,LinkedList<TValue>>

Example usages


The following are examples where TKey and TValue are replaced with real data types such as string or int:

  • Dictionary<string,List<DateTime>>
  • SortedDictionary<string,Queue<int>>
  • SortedList<int,Stack<float>>
  • Dictionary<string,LinkedList<int>>

Some situations where this pattern can be used


One-to-many value mapping can be used in the following situations:

  • Mapping all the grades obtained by a student. The ID of the student can be the key and the grades obtained in each subject (which may be duplicate) can be stored as the values in a list.
  • Tracking all the followers of a Twitter account. The user ID for the account will be the key and all follower IDs can be stored as values in a list.
  • Scheduling all the appointments for a patient whose user ID will serve as the key.

Pattern 4: Many-to-many mapping


Many-to-many mapping maps many elements of a group to many elements in other groups. Both can have duplicate entries.

Pattern interface


The following are the interface implementations of this pattern:

  • IEnumerable<Tuple<T1,T2,..,ISet<Tresult>>>
  • IEnumerable<Tuple<T1,T2,..,ICollection<Tresult>>>

Some concrete implementations


A concrete implementation of this pattern is as follows:
IList<Tuple<T1,T2,T3,HashSet<TResult>>>

Example usages


The following are examples where TKey and TValue are replaced with real data types such as string or int:

  • List<Tuple<string,int,int,int>>
  • List<Tuple<string,int,int,int,HashSet<float>>>

Some situations where this pattern can be used


Many-to-many mapping can be used in the following situations:

  • If many independent values can be mapped to a set of values, then these patterns should be used. ISet<T> implementations don't allow duplicates while ICollection<T> implementations, such as IList<T>, do.
  • Imagine a company wants to give a pay hike to its employees based on certain conditions. In this situation, the parameters for conditions can be the independent variable of the Tuples, and IDs of employees eligible for the hike can be stored in an ISet<T> implementation.


For concurrency support, replace non-concurrent implementations with their concurrent cousins. For example, replace Dictionary<TKey,TValue> with ConcurrentDictionary<TKey,TValue>.