Je sais qu'il n'est pas possible d'hériter des constructeurs en C #, mais il y a probablement un moyen de faire ce que je veux faire.
J'ai une classe de base héritée de nombreuses autres classes, et elle a une méthode Init
qui effectue une initialisation en prenant 1 paramètre. Toutes les autres classes héritées ont également besoin de cette initialisation, mais je devrais créer des constructeurs distincts pour toutes celles qui voudraient:
public Constructor(Parameter p) {
base.Init(p);
}
Cela viole totalement les principes DRY! Comment puis-je initialiser tous les éléments nécessaires sans créer des dizaines de constructeurs?
Vous n'avez pas besoin de créer des charges de constructeurs, tous avec le même code; vous n'en créez qu'une, mais les classes dérivées appellent le constructeur de base:
public class Base
{
public Base(Parameter p)
{
Init(p)
}
Init(Parameter p)
{
// common initialisation code
}
}
public class Derived : Base
{
public Derived(Parameter p) : base(p)
{
}
}
Modifiez la fonction init pour qu'elle soit le constructeur de la classe de base, puis appelez-la à partir des objets hérités comme ceci:
public InheritedObject(Parameter p) : base(p)
{
}
Le constructeur de base sera invoqué avant l'exécution de tout code dans le constructeur lui-même.
La seule façon de ne pas répéter le base.Init
l'appel consiste à appeler à la place le constructeur de base
class Base
{
public Base(Parameter p)
{
this.Init(p)
}
private void Init(Parameter p)
{
...
}
}
class Inherited : Base
{
public Inherited(Parameter p)
: base(p)
{
// other constructor logic, but Init is already called.
}
}
Vous ne pouvez pas hériter de constructeurs mais vous pouvez les appeler à partir des constructeurs de vos enfants dérivés. Si vous rendez privé le constructeur par défaut des classes de base, cela vous obligera à sélectionner un constructeur de base à chaque fois que vous créez une classe dérivée.
class A
{
protected A(int x)
{
}
}
class B : A
{
B(int x)
: base(x)
{
}
}
Quelque chose comme ça?
public Constructor(Parameter p) : base(p) {
}
Et la classe de base:
public Base(Parameter p)
{
Init(p);
}
Vous pouvez même marquer votre méthode Init
comme virtuelle, vous pouvez donc faire un remplacement doux dans vos autres classes, si besoin est! ;)
public virtual void Init() { }
et dans vos autres classes:
public override void Init() { base.Init(); //Do other stuff }