我有一些嵌套类-flto
和BaseOuter
,还有子类BaseInner
和DerivedOuter
。 DerivedInner
具有属性BaseOuter
,当实例化BaseInner baseInner;
时,我希望DerivedOuter
属性的运行时类型为baseInner
。
我首先像下面一样解决了这个问题,使用虚拟初始化器实例化DerivedInner
,该初始化器在baseInner
中被覆盖。这样一来,我就可以在各自的初始化程序中进行DerivedOuter
与baseInner = new BaseInner();
的对比。
注意到Resharper warning并做了little more reading之后,我决定应该更改它……但是如何?
我想到了几件事。我可以在调用构造函数之后调用初始化程序,这需要调用代码来完成baseInner = new DerivedInner();
。我可能可以使用工厂,但是我必须考虑一下。最后,也许我想做的类嵌套中存在设计缺陷?
值得指出的是,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;
}
}
}
}
所有代码都可以在此.NET Fiddle中找到。
答案 0 :(得分:1)
这是一种方法。
它在做同样的事情。区别在于派生类如何“替代” BaseInner
的实现。它通过向构造函数提供实现来实现。
internal class BaseOuter
{
protected BaseInner baseInner;
protected internal BaseOuter(BaseInner inner = null)
{
baseInner = inner ?? new BaseInner();
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
}
protected internal class BaseInner
{
public int x;
public BaseInner()
{
/* stuff that is needed in DerivedInner too */
Console.WriteLine(" BaseInner Constructor");
x = 2;
}
}
}
internal class DerivedOuter : BaseOuter
{
protected internal DerivedOuter()
:base(new DerivedInner())
{
Console.WriteLine("DerivedOuter Constructor (finished)");
}
protected internal class DerivedInner : BaseInner
{
public double y;
public DerivedInner()
{
Console.WriteLine(" DerivedInner Constructor");
y = 2d;
}
}
}
如果要进行全面的依赖注入,则可以从
中删除默认值protected internal BaseOuter(BaseInner inner = null)
这意味着BaseOuter
将与BaseInner
的任何实现完全脱钩。
其他一些建议:
baseInner
,则将其标记为readonly
。 (ReSharper可能会建议。)