Index initializer behavior

How different collection initialization styles behavior differs

Home DailyDrop

Daily Knowledge Drop

The index initialization style of collection initialization has slightly different (but important) behavior to that of the "traditional" initialization method.


Initialization

Let's look at a few different ways a Dictionary<int, string> can be initialized, and have 5 values set:

// initialize a empty dictionary, then add the values
var normalDictionary = new Dictionary<int, string>();
normalDictionary.Add(1, "one");
normalDictionary.Add(2, "two");
normalDictionary.Add(3, "three");
normalDictionary.Add(4, "four");
normalDictionary.Add(5, "five");

// initialize using the "traditional" method of collection initialization
var normalInitDictionary = new Dictionary<int, string>
{
    { 1, "one" },
    { 2, "two" },
    { 3, "three" },
    { 4, "four" },
    { 5, "five" }
};

// initialize using the index initialization
var indexInitDictionary = new Dictionary<int, string>
{
    [1] = "one",
    [2] = "two",
    [3] = "three",
    [4] = "four",
    [5] = "five"
};

All 3 of the above example will result in the same outcome - a dictionary with 5 items.

Apart from the difference in style and ease of reading (which is subjective, but personally I prefer the index initialization style), there is a subtle but very important difference to how the two methods operate internally.


Differences

The two difference ways of initializing the dictionary are lowered completely differently by the compiler:

Traditional initialization:

// initialize using the "traditional" method of collection initialization
var normalInitDictionary = new Dictionary<int, string>
{
    { 1, "one" },
    { 2, "two" },
    { 3, "three" },
    { 4, "four" },
    { 5, "five" }
};

// THE ABOVE GETS LOWERED TO:

Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(1, "one");
dictionary.Add(2, "two");
dictionary.Add(3, "three");
dictionary.Add(4, "four");
dictionary.Add(5, "five");


While using index initialization:

// initialize using the index initialization
var indexInitDictionary = new Dictionary<int, string>
{
    [1] = "one",
    [2] = "two",
    [3] = "three",
    [4] = "four",
    [5] = "five"
};

// THE ABOVE GETS LOWERED TO:

Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary[1] = "one";
dictionary[2] = "two";
dictionary[3] = "three";
dictionary[4] = "four";
dictionary[5] = "five";

Why the differences matter

The way in which the code gets lowered makes a difference, as it results in different behavior when having duplicate keys:

Traditional initialization:

// initialize using the "traditional" method of collection initialization
var normalInitDictionary = new Dictionary<int, string>
{
    { 1, "one" },
    { 1, "two" }
};

// THE ABOVE GETS LOWERED TO:

// This will result in an exception being thrown
Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(1, "one");
dictionary.Add(1, "two");

Initialization on a Dictionary with duplicate keys will result in an exception as the code gets lowered to having two Add method with the same key. This is not allowed.

With index initialization:

// initialize using the index initialization
var indexInitDictionary = new Dictionary<int, string>
{
    [1] = "one",
    [1] = "two",
};

// The above gets lower to:

Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary[1] = "one";
dictionary[1] = "two";

Duplicate keys with index initialization will NOT result in an exception as the code gets lowered to use the indexers, which will just result in the existing value ("one" in this case) being overwritten.


Notes

Subtle difference in how the two initialization methods operate, but can come with consequences if used without being aware of the differences.

Ignoring the operational differences, then it comes down to preference of style and ease of readability - performance difference between the two is negligible (less than 1% difference when tested)


References

7 New Cool Features in C# 6.0

Daily Drop 65: 03-05-2022

At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.

The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.
c# .net collection dictionary index initialization