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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With