У меня есть несколько вложенных классов, BaseOuter
и BaseInner
, и дочерние классы DerivedOuter
и DerivedInner
.BaseOuter
имеет свойство BaseInner baseInner;
, и когда я создаю экземпляр DerivedOuter
, я хочу, чтобы тип времени выполнения свойства baseInner
был DerivedInner
.
Сначала я решил эту проблему, как показано ниже, используя виртуальныйинициализатор для создания экземпляра baseInner
, который переопределяется в DerivedOuter
.Это позволяет мне делать baseInner = new BaseInner();
против baseInner = new DerivedInner();
в соответствующих инициализаторах.
После того, как я заметил Resharper Warning и сделал немного больше чтения , я решил, что долженизменить это ... но как?
Несколько вещей приходят на ум.Я мог бы вызвать инициализатор после вызова конструктора, требуя вызова кода для выполнения var baseOuter = new BaseOuter(); baseOuter.Initialize();
.Я, вероятно, могу использовать фабрику, но мне придется немного подумать об этом.И, наконец, возможно, есть недостаток дизайна во вложении классов, которое я хочу сделать?
Стоит отметить, что выполнение new BaseInner();
стоит дорого, и я не просто хочу его создать и выбросить.
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;
}
}
}
}
Вывод
new BaseOuter
BaseOuter Constructor
BaseOuter Initialize BaseInner
BaseInner Constructor
new DerivedOuter
BaseOuter Constructor
DerivedOuter Initialize DerivedInner
BaseInner Constructor
DerivedInner Constructor
DerivedOuter Constructor (finished)
Весь код можно найти здесь в этой .NET Fiddle .