Recently, I came across some code that looked like this:
public class Test
{
public ICollection<string> Things { get; set; }
public Test()
{
Things = new List<string> { "First" };
}
public static Test Factory()
{
return new Test
{
Things = { "Second" }
};
}
}
Calling Test.Factory()
results in a Test
object with a Things
collection containing both "First"
and "Second"
.
It looks like the line Things = { "Second" }
calls the Add
method of Things
. If the ICollection
is changed to an IEnumerable
, there is a syntax error stating "IEnumerable<string> does not contain a definition for 'Add'
".
It is also apparent that you can only use this kind of syntax in an object initialiser. Code such as this is invalid:
var test = new Test();
test.Things = { "Test" };
What is the name of this feature? In which version of C# was it introduced? Why is it only available in object initialisers?
It is called a collection initializer and it was added in the C# 3 language specifications (section 7.5.10.3 at introduction, section 7.6.10.3 in the current specs). To be specific, the code you use uses an embedded collection initializer.
Collection initializer actually just call the Add
method, which is required according to the specs.
As Quantic commented, the specs say:
A member initializer that specifies a collection initializer after the equals sign is an initialization of an embedded collection. Instead of assigning a new collection to the field or property, the elements given in the initializer are added to the collection referenced by the field or property.
That explains your unexpected results quite good.
Why is it only available in object initialisers?
Because it doesn't make sense elsewhere. You could just call the Add
method yourself instead of using initializers for something else than initializing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With