Why Prefer Collection Initializer

When it was first introduced, object initializer wasn't allowed to access indexer. This changed in C# 6, and we could now access the indexer within the object initializer. This eventually lead to a common initializing pattern which we often encouter in our daily code. 
  1. var dictionary = new Dictionary<int,string>  
  2. {  
  3.     [0] = "value 1",  
  4.     [1] = "value 2",  
  5. };  
In the above code, we used the object initializer to initialize the Dictionary. Prior to C# 6, we used Collection Initializer to initialize a collection. For example,
  1. var dictionary = new Dictionary<int,string>  
  2. {  
  3.     {0,"value 1"},  
  4.     {1,"value 2"},  
  5. };  
Of course the object initializer syntax looks more concise and cleaner, but are there any hidden threats with the approach ?
 
While both codes look similiar, they are accomplishing the objective via two different approaches, which results in different behaviors under certain circumstance, particularly if you were to accidently slip in a duplicate entry. 
  1. // Using Object Initializer   
  2. var dictionary = new Dictionary<int,string>  
  3. {  
  4.     [0] = "value 1",  
  5.     [1] = "value 2",  
  6.     [1] = "value 3"  
  7. };  
  8.   
  9. // Using Collection Initializer.  
  10. var dictionary = new Dictionary<int,string>  
  11. {  
  12.     {0,"value 1"},  
  13.     {1,"value 2"},  
  14.     {1,"value 3"}  
  15. };  
If one was to execute the above two code snippets, the approach using object initializer not throw any exception, while the approach using collection initializer would raise the much needed exception notifying the developer about the duplicate entry.
 
To understand why this happens, let us examine what happens behind each of them. The object initalizer would be translated to the following. 
  1. Dictionary<intstring> dictionary = new Dictionary<intstring>();  
  2. dictionary[0] = "value 1";  
  3. dictionary[1] = "value 2";  
  4. dictionary[1] = "value 3";  
The object initializer, after C# 6, allowed us to access the indexers and assign the value. This would mean, if there are duplicates, they are overwritten. Using the object initializer syntax, dictionary[1] == "value 3" holds true. The value 2 value gets overwritten with value 3 in the above example.
 
This is different when using the collection initializer. The collection initializer effectively calls the Add() method with appropriate signature. This would mean the approach with Collection Initializer would translate as
  1. Dictionary<intstring> dictionary = new Dictionary<intstring>();  
  2. dictionary.Add(0,"value 1");  
  3. dictionary.Add(1,"value 2");  
  4. dictionary.Add(1,"value 3");  
Obviously, adding a duplicate key would throw an exception in this case. As a developer, I must admit that  chances of accidental duplicates aren't that rare. Such mistakes could happen to any developer. Under such circumstances, it would be preferable that the exceptions be raised rather than values being overwritten without any notification.
 
Considering both approaches, it might be recommmended to use the collection initializers rather than depending on object initializer when dealing with Collections even if the syntax looks less concise than the object initializer.


Next Recommended Reading Empty Collections In C#