C# 6.0's new Dictionary Initializer - Clarification

The main advantage here with a dictionary is consistency. With a dictionary, initialization did not look the same as usage.

For example, you could do:

var dict = new Dictionary<int,string>();
dict[3] = "foo";
dict[42] = "bar";

But using initialization syntax, you had to use braces:

var dict = new Dictionary<int,string>
{
    {3, "foo"},
    {42, "bar"}
};

The new C# 6 index initialization syntax makes initialization syntax more consistent with index usage:

var dict = new Dictionary<int,string>
{ 
    [3] = "foo",
    [42] = "bar"
};

However, a bigger advantage is that this syntax also provides the benefit of allowing you to initialize other types. Any type with an indexer will allow initialization via this syntax, where the old collection initializers only works with types that implement IEnumerable<T> and have an Add method. That happened to work with a Dictionary<TKey,TValue>, but that doesn't mean that it worked with any index based type.


The code in the first case uses the collection initializer syntax. To be able to use the collection initializer syntax, a class must:

Collection Initializers:

  1. Implement the IEnumerable interface.
  2. Define an accessible Add() method. (as of C#6/VS2015, it may be an extension method)

So a class defined like so may use the syntax:

public class CollectionInitializable : IEnumerable
{
    public void Add(int value) { ... }
    public void Add(string key, int value) { ... }
    public IEnumerator GetEnumerator() { ... }
}

var obj = new CollectionInitializable
{
    1,
    { "two", 3 },
};

Not all objects are IEnumerable or has an add method and therefore cannot use that syntax.


On the other hand, many objects define (settable) indexers. This is where the dicionary initializer is used. It might make sense to have indexers but not necessarily be IEnumerable. With the dictionary initializer, you don't need to be IEnumerable, you don't need an Add() method, you only need an indexer.

Being able fully initialize an object in a single expression is generally useful (and in some contexts, a requirement). The dictionary initializer syntax makes it easier to do that without the steep requirements of using collection initializers.


It may be a questionable feature, but the new syntax allows you to set the same multiple times.

        private static Dictionary<string, string> test1
        = new Dictionary<string, string>() {
            ["a"] = "b",
            ["a"] = "c"
        };

is allowed: here the key "a" has the value "c".

In contrast, using

private static Dictionary<string, string> test2
    = new Dictionary<string, string>() {
        { "a","b" },
        { "a","c" },
    };

creates an exception:

Unbehandelte Ausnahme: System.TypeInitializationException: Der Typeninitialisierer für "ConsoleApplication1.Program" hat eine Ausnahme verursacht. 
---> System.ArgumentException: Ein Element mit dem gleichen Schlüssel wurde bereits hinzugefügt.
   bei System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   bei System.Collections.Generic.Dictionary``2.Insert(TKey key, TValue value, Boolean add)
   bei System.Collections.Generic.Dictionary``2.Add(TKey key, TValue value)
   bei ConsoleApplication1.Program..cctor() in Program.cs:Zeile 19.
   --- Ende der internen Ausnahmestapelüberwachung ---
   bei ConsoleApplication1.Program.Main(String[] args)