Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

covariant object initializers?

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...

like image 705
Homde Avatar asked Jan 23 '11 12:01

Homde


People also ask

What are initializers in C#?

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.

What is object initializer?

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.

How do you initiate an object in C#?

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.


1 Answers

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.

like image 115
Eric Lippert Avatar answered Sep 20 '22 23:09

Eric Lippert