It seems object initializer is not the same as constructor + property assignment. How so?

Viewed 168

Consider the code below:

class Data
{
    public string Name;
    public string NameWithSufix;
}

class Behaviour
{
    private Data data;
    public string Name { get { return data.Name; } private set { } }

    public Behaviour()
    {
        data = new Data()
        {
            Name = "My Name",
            NameWithSufix = Name + " Sufix",
        };
        //data = new Data();
        //data.Name = "My Name";
        //data.NameWithSufix = Name + " Sufix";
    }
}

class Program
{
    static void Main(string[] args)
    {
        Behaviour behaviour = new Behaviour();
    }
}

If you run this program, it will fail with NullReferenceException at Name property. This and this answer and Visual Studio try to persuade me object initializer and object constructors followed by property assignment are the same but it doesn't seem so. If I swap the body of constructor with commented code, it works. It seem like initiliazer doesn't actually run the constructor before it tries to assign properties. Why?

2 Answers

Name in NameWithSufix = Name points to data.Name, from which data is null at the time. A better representation for what object initializers do is this:

Data d = new Data();
d.Name = "My Name";
d.NameWithSufix = this.data.Name /*Name*/ + " Sufix"; // <-- see the problem here

this.data = d;

See that this.data isn't set until the object initializer is done.

This is supported by the C# language specification, as noted by PetSerAl.

It's running the Behavior constructor first. The problem is that the initialization of the Data class is not yet complete, so the following reference throws an exception

NameWithSufix = Name + " Sufix",

Because it calls get { return data.Name; } but data is still null at this point.


Update:

Patrick Hofman states it better and more accurately in his answer - it's not that the initialization of the Data class isn't complete, but that the new instance has not been assigned to the data variable yet.

Also, he requested a clarification to the official docs - give it a thumbs up if you agree.

Related