What is the difference between these two variations of collection initialiser expressions?

Tagc 09/16/2017. 1 answers, 803 views
c# collection-initializer

I've been using C# for a while, but recently noticed that the behaviour of one of my unit tests changed depending on which variation of collection initialiser expression I used:

  • var object = new Class { SomeCollection = new List<int> { 1, 2, 3 } };
  • var object = new Class { SomeCollection = { 1, 2, 3 } };

Up until this point I assumed that the second form was just syntactic sugar and was semantically equivalent to the first form. However, switching between these two forms resulted in my failing unit test passing.

The example code below demonstrates this:

void Main()
{
    var foo1 = new Foo { Items = new List<int> { 1, 2, 3} };
    var foo2 = new Foo { Items = { 1, 2, 3 } };

    foo1.Dump();
    foo2.Dump();
}

class Foo
{
    public List<int> Items { get; set; }
}

When I run this, the first assignment works fine but the second results in a NullReferenceException.

My gut feeling is that behind the scenes the compiler is treating these two expressions as this:

var foo1 = new Foo();
foo1.Items = new List<int> { 1, 2, 3 }; 

var foo2 = new Foo();
foo2.Items.Add(1);
foo2.Items.Add(2);
foo2.Items.Add(3);

Is that assumption accurate?

1 Comments
Leon Barkan 07/31/2017
That will help you : c-sharpcorner.com/article/…

1 Answers


Jon Skeet 07/31/2017.

Yes, your assumption is accurate. If an object initializer just has:

{
    Property = { ... }
}

rather than

{
    Property = expression
}

then the setter for the property isn't used - the getter is used, and then either the Add method is called, or properties are set within the returned value. So:

var foo = new Foo
{
    Collection = { 1 }
    Property =
    {
        Value = 1
    }
};

is equivalent to:

// Only the *getters* for Collection and Property are called
var foo = new Foo();
foo.Collection.Add(1);
foo.Property.Value = 1;

Compare that with:

var foo = new Foo
{
    Collection = new List<int> { 1 },
    Property = new Bar { Value = 1 }
};

which is equivalent to:

// The setters for Collection and Property are called
var foo = new Foo();
foo.Collection = new List<int> { 1 };
foo.Property = new Bar { Value = 1 };
1 comments
1 Ash Burlaczenko 07/31/2017
Shouldn't the equivalent to also new the collection or does it just add?

Related questions

Hot questions

Language

Popular Tags