Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

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?

like image 589
Dread Boy Avatar asked Mar 08 '23 13:03

Dread Boy


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.

like image 159
Patrick Hofman Avatar answered Mar 11 '23 11:03

Patrick Hofman


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.

like image 35
Grant Winney Avatar answered Mar 11 '23 09:03

Grant Winney