I have some nested classes, BaseOuter
and BaseInner
, and child classes DerivedOuter
and DerivedInner
. BaseOuter
has property BaseInner baseInner;
, and when I instantiate DerivedOuter
I want the runtime type of baseInner
property to be DerivedInner
.
I first solved this like I have below, using a virtual initializer to instantiate baseInner
, that is overriden in DerivedOuter
. That allows me to do baseInner = new BaseInner();
vs baseInner = new DerivedInner();
in the respective initializers.
After noticing a Resharper warning and doing a little more reading I decided I should change it... but how?
A couple of things come to mind. I could call the initializer after calling the constructor, requiring calling code to do var baseOuter = new BaseOuter(); baseOuter.Initialize();
. I can probably use a factory, but I'd have to think about that a little. Lastly, perhaps there is a design flaw in the class-nesting I want to do?
It's worth pointing out that doing new BaseInner();
is expensive, and I don't simply want to create it and throw it away.
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("new BaseOuter");
var baseOuter = new BaseOuter();
Console.WriteLine("\nnew DerivedOuter");
var derivedOuter = new DerivedOuter();
}
class BaseOuter{
protected BaseInner baseInner;
public BaseOuter(){
Console.WriteLine("BaseOuter Constructor");
/* lots of stuff I want in derived class */
// This is an anti-pattern I want to avoid
//https://www.jetbrains.com/help/resharper/2018.2/VirtualMemberCallInConstructor.html
InitializeInner();
}
protected virtual void InitializeInner(){
Console.WriteLine(" BaseOuter Initialize BaseInner");
baseInner = new BaseInner();
}
protected class BaseInner{
public int x;
public BaseInner(){
/* stuff that is needed in DerivedInner too */
Console.WriteLine(" BaseInner Constructor");
x = 2;
}
}
}
class DerivedOuter : BaseOuter {
public DerivedOuter() {
Console.WriteLine("DerivedOuter Constructor (finished)");
}
protected override void InitializeInner(){
Console.WriteLine(" DerivedOuter Initialize DerivedInner");
baseInner = new DerivedInner();
}
protected class DerivedInner : BaseInner {
public double y;
public DerivedInner(){
Console.WriteLine(" DerivedInner Constructor");
y = 2d;
}
}
}
}
All of the code can be found here in this .NET Fiddle.
Aucun commentaire:
Enregistrer un commentaire