I know that calling a virtual method from a base class constructor can be dangerous since the child class might not be in a valid state. (at least in C#)
My question is what if the virtual method is the one who initializes the state of the object ? Is it good practice or should it be a two step process, first to create the object and then to load the state ?
First option: (using the constructor to initialize the state)
public class BaseObject { public BaseObject(XElement definition) { this.LoadState(definition); } protected abstract LoadState(XElement definition); }
Second option: (using a two step process)
public class BaseObject { public void LoadState(XElement definition) { this.LoadStateCore(definition); } protected abstract LoadStateCore(XElement definition); }
In the first method the consumer of the code can create and initialize the object with one statement:
// The base class will call the virtual method to load the state. ChildObject o = new ChildObject(definition)
In the second method the consumer will have to create the object and then load the state:
ChildObject o = new ChildObject(); o.LoadState(definition);
(This answer applies to C# and Java. I believe C++ works differently on this matter.)
Calling a virtual method in a constructor is indeed dangerous, but sometimes it can end up with the cleanest code.
I would try to avoid it where possible, but without bending the design hugely. (For instance, the ‘initialize later’ option prohibits immutability.) If you do use a virtual method in the constructor, document it very strongly. So long as everyone involved is aware of what it’s doing, it shouldn’t cause too many problems. I would try to limit the visibility though, as you’ve done in your first example.
EDIT: One thing which is important here is that there’s a difference between C# and Java in order of initialization. If you have a class such as:
where the
Parentconstructor callsShowFoo, in C# it will display 10. The equivalent program in Java would display 0.