asm*_*smo 38 c# constructor code-design
正如您在下面的代码中看到的那样,在构造Child对象期间,在Init()之前调用DoStuff()方法.
我的情况是,我有很多子课.因此,在每个子节点的构造函数中的Init()之后直接重复调用DoStuff()方法将不是一个优雅的解决方案.
有没有办法在父类中创建某种post构造函数,它将在子构造函数之后执行?这样,我可以在那里调用DoStuff()方法.
如果您有任何其他设计理念可以解决我的问题,我也想听听它!
abstract class Parent
{
public Parent()
{
DoStuff();
}
protected abstract void DoStuff();
}
class Child : Parent
{
public Child()
// DoStuff is called here before Init
// because of the preconstruction
{
Init();
}
private void Init()
{
// needs to be called before doing stuff
}
protected override void DoStuff()
{
// stuff
}
}
Run Code Online (Sandbox Code Playgroud)
Jak*_*cki 18
如果您有构造对象的复杂逻辑,那么请考虑FactoryMethod模式.
在你的情况下,我会把它作为一个简单的实现
public static Parent Construct(someParam)
Run Code Online (Sandbox Code Playgroud)
采用一些参数并基于它的方法决定实例化哪个子类.您可以DoStuff()从构造函数中删除方法调用,并Construct()在新实例上调用它.
此外,您应该避免构造函数中的虚拟/抽象方法调用.有关更多详细信息,请参阅此问题:构造函数中的虚拟成员调用
tay*_*onr 12
这个怎么样:
abstract class Parent
{
public Parent()
{
Init();
DoStuff();
}
protected abstract void DoStuff();
protected abstract void Init();
}
class Child : Parent
{
public Child()
{
}
protected override void Init()
{
// needs to be called before doing stuff
}
protected override void DoStuff()
{
// stuff
}
}
Run Code Online (Sandbox Code Playgroud)
让我介绍一些使用C#功能的一般解决方案。请注意,此解决方案不需要您在构造对象后使用工厂模式或调用任何方法,它可以在任何类上工作,只需使用单个方法实现接口即可。首先,我们声明一个我们的类必须实现的接口:
public interface IInitialize {
void OnInitialize();
}
Run Code Online (Sandbox Code Playgroud)
接下来,我们为此接口添加一个静态扩展类,并添加Initialize方法:
public static class InitializeExtensions
{
public static void Initialize<T>(this T obj) where T: IInitialize
{
if (obj.GetType() == typeof(T))
obj.OnInitialize();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我们需要一个类及其所有后代在对象完全构造后立即调用初始化程序,那么我们要做的就是实现IInitialize并在构造函数中添加一行:
public class Parent : IInitialize
{
public virtual void OnInitialize()
{
Console.WriteLine("Parent");
}
public Parent()
{
this.Initialize();
}
}
public class Child : Parent
{
public Child()
{
this.Initialize();
}
public override void OnInitialize()
{
Console.WriteLine("Child");
}
}
public class GrandChild : Child
{
public GrandChild()
{
this.Initialize();
}
public override void OnInitialize()
{
Console.WriteLine("GrandChild");
}
}
Run Code Online (Sandbox Code Playgroud)
诀窍是,当派生类调用扩展方法Initialize时,它将抑制任何未从实际类进行的调用。
正如其他人所提到的,您应该使用工厂模式。
public class Parent
{
public Parent()
{
}
public virtual void PostConstructor()
{
}
}
public class Child : Parent
{
public override void PostConstructor()
{
base.PostConstructor();
// Your code here
}
}
public void FactoryMethod<T>() where T : Parent
{
T newobject = new T();
newobject.PostConstructor();
}
Run Code Online (Sandbox Code Playgroud)