Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird syntax of collection initializers

Tags:

c#

Suppose, we have a very simple class:

class ObjectList {
    public List<string> List1 { get; } = new List<string>();
    public List<string> List2 { get; set; }
}

and we want to make an instance of this class:

ObjectList objectList = new ObjectList {
    List1 = { "asdf", "qwer" },
    List2 = new List<string> { "zxcv", "1234" }
};

So, in case of List2 it is ok, using "=" we set property. But in List1 case it looks like we set property, but actually, we suppose to set it somewhere before, and here we only set values. And it very similar to array initializing:

string[] arr = { "val1", "val2" }

Why C# uses this confusing syntax here?

Edit: I guess I confused many viewers with C# 6.0 syntax, but it's not the point. Let's use old good C# 3.0 and .net 2.0. And lets add more fun too this and add some values ("1" and "2") to the list from start, as Jeff Mercado recommended:

class Program {
    static void Main(string[] args) {
        ObjectList objectList = new ObjectList {
            List1 = { "asdf", "qwer" },
        };
    }
}
class ObjectList {
    List<string> _List1 = new List<string>() { "1", "2" };
    public List<string> List1 {
        get {
            return _List1;
        }
    }
}

It shows the same weird syntax. And at the end I have list { "1", "2", "asdf", "qwer" }, which is even more confusing. I can expect this the less.

like image 300
Alex Butenko Avatar asked Dec 21 '15 22:12

Alex Butenko


People also ask

What is collection initializers in C#?

Collection initializers let you specify one or more element initializers when you initialize a collection type that implements IEnumerable and has Add with the appropriate signature as an instance method or an extension method. The element initializers can be a simple value, an expression, or an object initializer.

How do you initialize an object?

Objects can be initialized using new Object() , Object. create() , or using the literal notation (initializer notation). An object initializer is a comma-delimited list of zero or more pairs of property names and associated values of an object, enclosed in curly braces ( {} ).

Does C# have initializer lists?

C# has a feature called Object Initializer. You can provide values which the compiler will use to initialize the specified members, and call the default constructor. For this to work you need to have a public default constructor.

What is object in C# with example?

Everything in C# is associated with classes and objects, along with its attributes and methods. For example: in real life, a car is an object. The car has attributes, such as weight and color, and methods, such as drive and brake. A Class is like an object constructor, or a "blueprint" for creating objects.


2 Answers

Why C# uses this confusing syntax here?

You are right that it's a little bit weird, but that's because you are mixing 2 principles. As several comments already pointed out, the { item1, items2 } syntax is converted to .Add(itemN) calls when the item on the left of the = is a Collection.

So the weirdness is a result of the fact that

List<SomeClass> list = new List<SomeClass> { item1, item2 };
SomeClass[] array = { item1, item2 };

are treated differently.

The other part is that your sample moves the new List<SomeClass> around, but it is there in both cases.

like image 79
Henk Holterman Avatar answered Oct 18 '22 20:10

Henk Holterman


The answer has been given by Eric Lippert in his answer to Why is an Add method required for { } initialization?

The by-design goal motivated by typical usage scenarios for collection initializers was to make initialization of existing collection types possible in an expression syntax so that collection initializers could be embedded in query comprehensions or converted to expression trees.

Every other scenario was lower priority; the feature exists at all because it helps make LINQ work.

So it seems that, even when this syntax makes more sense when creating readonly collections, it was added anyway so they can deliver LINQ on time.

like image 26
Carlos Muñoz Avatar answered Oct 18 '22 20:10

Carlos Muñoz