What benefits does dictionary initializers add over collection initializers?
Asked Answered
B

3

52

In a recent past there has been a lot of talk about whats new in C# 6.0
One of the most talked about feature is using Dictionary initializers in C# 6.0
But wait we have been using collection initializers to initialize the collections and can very well initialize a Dictionary also in .NET 4.0 and .NET 4.5 (Don't know about old version) like

Dictionary<int, string> myDict = new Dictionary<int, string>() {
    { 1,"Pankaj"},
    { 2,"Pankaj"},
    { 3,"Pankaj"}
};

So what is there new in C# 6.0, What Dictionary Initializer they are talking about in C# 6.0

Brazier answered 2/12, 2014 at 7:37 Comment(1)
@DevEstacion The question title could be edited to "What's the difference between collection and dictionary initializers" or "What benefits does dictionary initializers add over collection initializers" to differentiate from a "simple googleable question"Workbook
W
78

While you could initialize a dictionary with collection initializers, it's quite cumbersome. Especially for something that's supposed to be syntactic sugar.

Dictionary initializers are much cleaner:

var myDict = new Dictionary<int, string>
{
    [1] = "Pankaj",
    [2] = "Pankaj",
    [3] = "Pankaj"
};

More importantly these initializers aren't just for dictionaries, they can be used for any object supporting an indexer, for example List<T>:

var array = new[] { 1, 2, 3 };
var list = new List<int>(array) { [1] = 5 };
foreach (var item in list)
{
    Console.WriteLine(item);
}

Output:

1
5
3
Workbook answered 2/12, 2014 at 7:47 Comment(9)
It's not the same thing. The old version calls the Add method (that can now be an extension method in C#) and the new calls the indexer. The end result might be the same for dictionaries but the new one can be used on types that have indexers but not Add methods.Adelaideadelaja
@PauloMorgado Of course. I didn't suggest otherwise.Workbook
@I3arnon, no you didn't. When I read the question and your answer, I thought it might be misunderstood as being the same thing. I was just reinforcing your answer.Adelaideadelaja
Is the output of the example correct? I would've expected 5 2 3Slogan
@GuillermoRuffino indexes are zero-based.Workbook
@PauloMorgado Also there is another important side effect of calling indexer instead of Add, this will fail new Dictionary<int, string> { {1, "a"}, {1, "b"} }; but this will not new Dictionary<int, string> { [1] = "a", [1] = "b" }; (and the value of dict[1] is b, the latest assignment).Underdog
This must be born in mind especially if indexer are variables, instead of literals. With old syntax you get an exception, with the new syntax the first value is overwritten with no warnings.Underdog
And supports initializing objects that have an indexer but not an Add method.Adelaideadelaja
@Underdog that alone is the single most important difference. Would appreciate if i3arnon can incorporate that to his answer.Stylo
S
5

Just to stress the most important difference, dictionary initializer calls the indexer, and hence it performs an update when duplicate keys are encountered, whereas collection initializer calls the Add method which will throw.

To briefly summarize the differences in general:

  1. Collection initializer calls Add method (for IEnumerables) where as dictionary initializer calls indexer. This has the Add vs Update semantic differences for dictionaries.

  2. Dictionary initializer is technically an object initializer, hence can be mixed with initializing other properties. For e.g.:

    new Dictionary<int, string>
    {
        [1] = "Pankaj",
        [2] = "Pankaj",
        [3] = "Pankaj",
        Capacity = 100,
    };
    

    but not

    new Dictionary<int, string>() 
    {
        { 1,"Pankaj" },
        { 2,"Pankaj" },
        { 3,"Pankaj" },
        Capacity = 100, // wont compile
    };
    
  3. Being just an object initializer, indexed initializer can be used for any class with an indexer, whereas collection initializer can be used only for IEnumerables, which should be obvious anyway.

  4. Collection initializer can be enhanced with custom Add extension methods, whereas ditionary initializer can't be (no extension indexer in C# yet).

  5. Dictionary initializer maybe subjectively slightly more readable when it comes to initializing a dictionary :)

  6. Dictionary initializer is C# 6.0 feature whereas collection initializer is available from C# 3.0 onwards.

Stylo answered 6/3, 2020 at 12:48 Comment(0)
I
0

New is creating a dictionary this way

Dictionary<int, string> myDict = new Dictionary<int, string>() {
    [1] = "Pankaj",
    [2] = "Pankaj",
    [3] = "Pankaj"
};

with the style of <index> = <value>

Obsolete: string indexed member syntax (as stated in the comments)

Dictionary<int, string> myDict = new Dictionary<int, string>() {
        $1 = "Pankaj",
        $2 = "Pankaj",
        $3 = "Pankaj"
    };

Taken from A C# 6.0 Language Preview

To understand the $ operator, take a look at the AreEqual function call. Notice the Dictionary member invocation of “$Boolean” on the builtInDataTypes variable—even though there’s no “Boolean” member on Dictionary. Such an explicit member isn’t required because the $ operator invokes the indexed member on the dictionary, the equivalent of calling buildInDataTypes["Boolean"].

Iridectomy answered 2/12, 2014 at 7:47 Comment(1)
AFAIK the $ operator doesn't exist anymore.Workbook

© 2022 - 2024 — McMap. All rights reserved.