The below code might look odd in functionality. This is because this is a simplified presentation of something bigger.
I have a class
named Person and the person has 1 property
named string Name.
In another class
named ClassRoom I have the following constructors
:
protected ClassRoom() { }
public ClassRoom(Person person) : this(person == null ? null : person, person.Name) { }
public ClassRoom(Person person, string name)
{
// Possible NullReferenceException which is not that important because it can be anticipated on.
person.Name = name;
}
My goal with ClassRoom(Person person)
is that, if the Person is null, ClassRoom()
is called and if it's not null ClassRoom(Person person, string name)
is called.
To make sure this is working I wrote a Unit Test. When I do new ClassRoom(null)
in my test, a NullReferenceException is thrown in ClassRoom(Person person, string name)
which surprises me. If the Person in ClassRoom(Person person)
is null, shouldn't ClassRoom()
be called instead of ClassRoom(Person person, string name)
?
My goal with ClassRoom(Person person) is that, if the Person is null, ClassRoom() is called and if it's not null ClassRoom(Person person, string name) is called.
You can't do that, basically. You can't decide which constructor to chain to at execution time. Overload resolution is performed at compile-time, and that's what determines what you're chaining to. It's not clear why you'd expect your current code to do it anyway, but you can't do it at all.
Basically you should reconsider your design. Typically, it's a good idea for constructors with fewer parameters to call constructors with more parameters, passing in default values. For example:
protected ClassRoom() : this(null)
{
}
public ClassRoom(Person person)
: this(person, person == null ? "" : person.Name)
{
}
public ClassRoom(Person person, string name)
{
this.person = person;
this.name = name;
}
See more on this question at Stackoverflow