web-dev-qa-db-fra.com

Puis-je hériter des constructeurs?

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?

46
Alex

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)
    {

    }
}
80
Rob Levine

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.

10
AHM

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.
   }
}
7
Jamiec

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)
    {

    }
}
3
rerun

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 }
2
Arcturus