say that I have an class that has a property that is a dictionary<string,bool>, using a object initializer I can use this syntax (which I think looks pretty clean):
new MyClass()
{
Table = { {"test",true},{"test",false} }
}
however, outside of the initializer I can't do this:
this.Table = { {"test",true},{"test",false} };
Why are initializers a special case? I'd hazard a guess that it has something to do with LINQ requirements, covariance or whatnot but it feels a little incongruent not being able to use that kind of initializer everywhere...
Object initializers let you assign values to any accessible fields or properties of an object at creation time without having to invoke a constructor followed by lines of assignment statements.
An object initializer is an expression that describes the initialization of an Object . Objects consist of properties, which are used to describe an object. The values of object properties can either contain primitive data types or other objects.
The compiler processes object initializers by first accessing the parameterless instance constructor and then processing the member initializations. Therefore, if the parameterless constructor is declared as private in the class, object initializers that require public access will fail.
The question is somewhat confusing, as the question has nothing to do with LINQ, nothing to do with generic variance, and features a collection initializer, as well as an object initializer. The real question is, as far as I can tell "why is it not legal to use a collection initializer outside of an object creation expression?"
The relevant design principle here is that in general, we want operations that create and initialize objects to have the word "new" in them somewhere as a signal to the reader that there is an object creation happening here. (Yes, there are a few exceptions to this rule in C#. As an exercise to the reader, see if you can name them all.)
Doing things your way makes it harder to reason about the code. Quick, what does this do?
d = new List<int>() { 10, 20, 30 };
d = { 40, 50, 60 };
Does the second line append 40, 50, 60 to the existing list? Or does it replace the old list with a new one? There's no "new" in there, so does the reader have an expectation that a new object has been created?
When you say
q = new Whatever() { MyList = { 40, 50, 60 } };
that doesn't create a new list; it appends 40, 50, 60 to an existing list allocated by the constructor. Your proposed syntax is therefore ambiguous and confusing as to whether a new list is created or not.
The proposed feature is both confusing and unnecessary, so it's unlikely to be implemented any time soon.
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