Skip to content
21 changes: 15 additions & 6 deletions standard/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -1984,7 +1984,7 @@ The run-time processing of an *object_creation_expression* of the form new `T(A)

#### 12.7.15.3 Object initializers

An ***object initializer*** specifies values for zero or more fields or properties of an object.
An ***object initializer*** specifies values for zero or more fields, properties, or indexed elements of an object.

```ANTLR
object_initializer
Expand All @@ -1997,7 +1997,12 @@ member_initializer_list
;

member_initializer
: identifier '=' initializer_value
: initializer_target '=' initializer_value
;

initializer_target
: identifier
| '[' argument_list ']'
;

initializer_value
Expand All @@ -2006,13 +2011,17 @@ initializer_value
;
```

An object initializer consists of a sequence of member initializers, enclosed by `{` and `}` tokens and separated by commas. Each member initializer shall name an accessible field or property of the object being initialized, followed by an equals sign and an expression or an object initializer or collection initializer. It is an error for an object initializer to include more than one member initializer for the same field or property. It is not possible for the object initializer to refer to the newly created object it is initializing.
An object initializer consists of a sequence of member initializers, enclosed by `{` and `}` tokens and separated by commas. Each *member_initializer* shall designate a target for the initialization. An *identifier* shall name an accessible field or property of the object being initialized, whereas an *argument_list* enclosed in square brackets shall specify arguments for an accessible indexer on the object being initialized. It is an error for an object initializer to include more than one member initializer for the same field or property.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth explicitly noting that it is okay to specify multiple member initializers that use indexers?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given it’s an error if the same field or property is initialised twice then yes something should be said about indexers – but what are the rules? Are the argument_list’s required to be distinct (as with fields/properties) or can the same indexed value be initialised more than once?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meeting notes: Yes, we want to spell this out, but we can do so in a follow-up PR.


A member initializer that specifies an expression after the equals sign is processed in the same way as an assignment ([§12.18.2](expressions.md#12182-simple-assignment)) to the field or property.
Each *initializer_target* is followed by an equals sign and either an expression, an object initializer or a collection initializer. It is not possible for expressions within the object initializer to refer to the newly created object it is initializing.

A member initializer that specifies an expression after the equals sign is processed in the same way as an assignment ([§12.18.2](expressions.md#12182-simple-assignment)) to the target.

A member initializer that specifies an object initializer after the equals sign is a ***nested object initializer***, i.e., an initialization of an embedded object. Instead of assigning a new value to the field or property, the assignments in the nested object initializer are treated as assignments to members of the field or property. Nested object initializers cannot be applied to properties with a value type, or to read-only fields with a value type.

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. The field or property shall be of a collection type that satisfies the requirements specified in [§12.7.15.4](expressions.md#127154-collection-initializers).
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 target field, property, or indexer, the elements given in the initializer are added to the collection referenced by the target. The target shall be of a collection type that satisfies the requirements specified in [§12.7.15.4](expressions.md#127154-collection-initializers).

When an initializer target refers to an indexer, the arguments to the indexer shall always be evaluated exactly once. Thus, even if the arguments end up never getting used (e.g., because of an empty nested initializer), they are evaluated for their side effects.

> *Example*: The following class represents a point with two coordinates:
> ```csharp
Expand Down Expand Up @@ -2127,7 +2136,7 @@ A collection initializer consists of a sequence of element initializers, enclose
> ```
> *end example*

The collection object to which a collection initializer is applied shall be of a type that implements `System.Collections.IEnumerable` or a compile-time error occurs. For each specified element in order, the collection initializer invokes an `Add` method on the target object with the expression list of the element initializer as argument list, applying normal overload resolution for each invocation. Thus, the collection object shall contain an applicable `Add` method for each element initializer.
The collection object to which a collection initializer is applied shall be of a type that implements `System.Collections.IEnumerable` or a compile-time error occurs. For each specified element in order, normal member lookup is applied to find a member named `Add`. If the result of the member lookup is not a method group, a compile-time error occurs. Otherwise, overload resolution is applied with the expression list of the element initializer as the argument list, and the collection initializer invokes the resulting method. Thus, the collection object shall contain an applicable instance or extension method with the name `Add` for each element initializer.

> *Example*:The following class represents a contact with a name and a list of phone numbers:
> ```csharp
Expand Down