c# - tipos - ¿Automáticamente los Constructores de Base están disponibles en clase derivada?
tipos de clases programacion (5)
¿Puedo decir "Tomar todos los constructores de la base" sin agregarlos todos?
No. :-(
Tengo una clase base con dos constructores que requieren un parámetro:
public abstract class StoreBase
{
private readonly SomeObject_sobj;
protected StoreBase(SomeObject sobj)
{
_sobj = sobj;
}
protected StoreBase(OtherObject oobj)
{
_sobj = new SomeObject(oobj);
}
}
Entonces tengo una clase derivada:
public class MyDerived: StoreBase
{
}
Esto provoca un error de compilación ya que la base class doesn''t contain parameterless constructor
.
Mi entendimiento es que debido a que MyDerived no contiene un constructor, el compilador agrega un constructor sin parámetros (que es bien conocido y no tiene nada que ver con las clases derivadas). Sin embargo, como se deriva de otra clase, el constructor de la clase base necesita ejecutarse primero, y no hay manera de determinar qué constructor debe ejecutarse desde el constructor MyDerived vacío.
Básicamente, estoy preguntando: ¿puedo evitar copiar / pegar todos los constructores de la Base en la clase Derivada si realmente no necesito una lógica de constructor adicional? ¿Puedo decir "Tomar todos los constructores de la base" sin agregarlos todos?
(Y sí, sé que podría / debería refactorizar esto en un constructor sin parámetros y un método de inicialización virtual protegido), pero todavía me pregunto si puedo trabajar con los constructores y todavía evitar copiar / pegar.
Desafortunadamente, la respuesta es no.
Una cosa que puedes hacer es llamar a la base desde tu constructor MyDerived:
class MyDerived: StoreBase
{
public MyDerived(OtherObject obj) : base (obj) {}
}
El compilador solo generará un constructor predeterminado (sin parámetros) si usted no ha proporcionado ningún constructor. Una vez que definas un constructor, el compilador no generará uno por ti.
Puede ser importante tener esto en cuenta si planea serializar su clase ya que la serialización requiere un constructor predeterminado. Si le asigna a su clase un constructor distinto al predeterminado, también deberá proporcionar uno predeterminado para admitir la serialización porque, nuevamente, una vez que proporcione cualquier constructor, el compilador no le proporcionará uno automáticamente.
No, los constructores no se heredan y no hay acceso directo para crear copias de los constructores base.
Lo más cercano es implementar constructores que llaman a los constructores base. Supongo que quieres hacerlos públicos de todos modos, para que puedas crear una instancia de la clase:
public MyDerived(SomeObject sobj) : base(sobj) {}
public MyDerived(OtherObject oobj) : base(oobj) {}
No, también deberá implementar los constructores (apropiados) en la clase derivada.
La clase derivada solo necesita usar uno de los constructores base, por lo que los constructores requeridos en él pueden ser completamente diferentes a la clase base. Deberán implementarse a mano, incluso si eso es solo:
public class MyDerived : StoreBase
{
public MyDerived(SomeObject sobj) : base(sobj) {}
public MyDerived(OtherObject oobj) : base(oobj) {}
}
También:
(Y sí, sé que podría / debería refactorizar esto en un constructor sin parámetros y un método de inicialización virtual protegido), pero todavía me pregunto si puedo trabajar con los constructores y todavía evitar copiar / pegar.
Aunque veo esto promocionado, creo que no siempre es una buena práctica. En muchos casos, esto es realmente problemático, ya que confía en la subclase para que llame correctamente a Initialize si anulan su método virtual protegido. Por ejemplo, si la subclase hizo esto, podría ser muy malo:
public class MyDerived : StoreBase
{
// .. other stuff
protected override void Initialize()
{
// Leave out, intentionally or accidentally, the following:
// base.Initialize();
}
}
De hecho, evito esto en la mayoría de las situaciones, e inicializo en los constructores (o en un método privado de inicialización no virtual). No hacerlo rompe cualquier garantía que tenga de que su inicialización siempre se producirá de la forma que pretende.
Los constructores y el encadenamiento de constructores proporcionan la misma funcionalidad, con garantías mucho mejores.