Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of operations using Object Initializer Syntax

Does the order in which I set properties using the object initializer syntax get executed in the exact same order?

For instance if I do this:

var s = new Person { FirstName = "Micah",                      LastName = "Martin",                      IsLoaded = true                    } 

will each property get set in the same order?

like image 406
Micah Avatar asked Jan 30 '09 14:01

Micah


People also ask

What is object initializer syntax?

The object initializers syntax allows you to create an instance, and after that it assigns the newly created object, with its assigned properties, to the variable in the assignment. Starting with C# 6, object initializers can set indexers, in addition to assigning fields and properties.

What is initialization syntax?

C# - Object Initializer Syntax NET 3.5) introduced Object Initializer Syntax, a new way to initialize an object of a class or collection. Object initializers allow you to assign values to the fields or properties at the time of creating an object without invoking a constructor. Example: Object Initializer Syntax.

How are Initializers executed in C#?

Initializers execute before the base class constructor for your type executes, and they are executed in the order in which the variables are declared in your class. Using initializers is the simplest way to avoid uninitialized variables in your types, but it's not perfect.

What is collection initializers in C#?

An object and collection initializer is an interesting and very useful feature of C# language. This feature provides a different way to initialize an object of a class or a collection. This feature is introduced in C# 3.0 or above.


1 Answers

Yes.

Apologies for getting interrupted (I have to actually do some work every so often). The spec doesn't explicitly say it, but it makes it pretty clear IMO in section 7.6.10.2:


An object initializer consists of a sequence of member initializers, enclosed by { and } tokens and separated by commas.

(Note the word "sequence" here, rather than "set". I personally think that's significant, as a sequence is ordered.)

The following class represents a point with two coordinates:

public class Point {     int x, y;     public int X { get { return x; } set { x = value; } }     public int Y { get { return y; } set { y = value; } } } 

An instance of Point can be created and initialized as follows:

Point a = new Point { X = 0, Y = 1 }; 

which has the same effect as

Point __a = new Point(); __a.X = 0; __a.Y = 1;  Point a = __a; 

where __a is an otherwise invisible and inaccessible temporary variable.


EDIT: I've had a response from Mads Torgersen, who has basically said that anything which can be done now will preserve the order. There may be some oddities in future where the order is not preserved in weird cases where you're doing something other than setting a property/field, but that will depend on where the language goes.

It's worth pointing out that there are actually lots of steps going on here - there's the order of execution of the evaluation of the arguments (i.e. the RHS bits) and the order of execution of the assignments. For example, if you have:

new Foo {     A = X,     B = Y } 

all the following orders are possible while still maintaining the order of the actual property execution (A and B):

  • Evaluate X, assign to A, evaluate Y, assign to B
  • Evaluate X, evaluate Y, assign to A, assign to B
  • Evaluate Y, evaluate X, assign to A, assign to B

I believe the first option is the one actually taken, but this was just to demonstrate that there's more to it than meets the eye.

I would also be very wary of actually writing code which depends on this...

like image 103
Jon Skeet Avatar answered Sep 18 '22 04:09

Jon Skeet