I noticed strange behaviour when initializing collection property.
Consider:
class X
{
public IList<int> Ints { get; set; }
}
I can initialize Ints
like that:
var theObject = new X
{
Ints = { 12, 3, 4, 5, 6 }
};
But I cannot do that:
var x = new X();
x.Ints = { 12, 3, 4, 5, 6 }
Any ideas why? It seems pretty unintuitive.
new X ...
is the start of an object creation expression. In this kind of expressions, an object or collection initializer is allowed:
object_creation_expression
: 'new' type '(' argument_list? ')' object_or_collection_initializer?
| 'new' type object_or_collection_initializer // <--- here!
;
object_or_collection_initializer
: object_initializer
| collection_initializer
;
In your code, you have an object initialiser { Ints = ... }
. Inside that, there is another collection initialiser { 12, 3, 4, 5, 6 }
. This is allowed, as per the grammar:
object_initializer
: '{' member_initializer_list? '}'
| '{' member_initializer_list ',' '}'
;
member_initializer_list
: member_initializer (',' member_initializer)*
;
member_initializer
: initializer_target '=' initializer_value
;
initializer_target
: identifier
| '[' argument_list ']'
;
initializer_value
: expression
| object_or_collection_initializer // <---- here!
;
An initializer_value
can either be an expression, or another object_or_collection_initializer
. This also implies that, though they may look like it, object_or_collection_initializer
, i.e. things like { 12, 3, 4, 5, 6 }
, are not a kind of expression.
On the other hand, assignments don't allow this. Assignments only allow an expression to be on the right hand side:
assignment
: unary_expression assignment_operator expression
;