MSDN claims that:
Using the collection initializer, you do not need to specify several calls to the add class method in the source code; the compiler adds calls.
They also give this example using the new syntax to initialize a collection using parentheses:
var numbers = new Dictionary<int, string> { [7] = "seven", [9] = "nine", [13] = "thirteen" };
However, when checking the generated IL code, it seems that this code does not lead to calls to the Add method at all, but rather to one set_item , for example:
IL_0007: ldstr "seven" IL_000c: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::set_Item(!0, !1)
The "old" curly brackets syntax, in contrast, gives the following:
// C# code: var numbers2 = new Dictionary<Int32, String> { {7, "seven"}, {9, "nine"}, {13, "thirteen"} }; // IL code snippet: // ---------- // IL_0033: ldstr "seven" // IL_0038: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::Add(!0/*int32*/, !1/*string*/)
... As you can see, the Add call is the result, as expected. (One can only assume that the text on MSDN mentioned above has not yet been updated.)
I have so far discovered one case where this difference really matters, and this is with the quirky System.Collections.Specialized.NameValueCollection . This allows a single key to point to multiple values. Initialization can be performed in both directions:
const String key = "sameKey"; const String value1 = "value1"; const String value2 = "value2"; var collection1 = new NameValueCollection { {key, value1}, {key, value2} }; var collection2 = new NameValueCollection { [key] = value1, [key] = value2 };
... But due to differences in how the first one actually calls NameValueCollection::Add(string, string) , the results differ when viewing the contents of each collection;
collection1 [key] = "value1, value2"
collection2 [key] = "value2"
I understand that there is a connection between the old syntax and the IEnumerable interface, and how the compiler finds the Add method by naming convention, etc. I also understand the benefits of any type of indexer subject to the new syntax, as discussed in this SO answer earlier.
Perhaps these are all the expected functions, from your point of view, but the consequences for me did not matter, and I am curious to know more.
So, I am wondering if there is a documentation source on MSDN or elsewhere that clarifies this difference in behavior that comes with a choice of syntax. I also wonder if you know of other examples where this choice can have the same effect as when initializing NameValueCollection .