sirven - Asegúrese de que el método base se llame en C#
palabras reservadas en c# y para que sirven (4)
Creo que la sugerencia que encontraste es buena.
El único método de clase base que no puede evitar llamar desde la subclase en el constructor de la clase base.
¿Puedo de alguna manera forzar a una clase derivada a llamar siempre a la base de métodos anulados?
public class BaseClass
{
public virtual void Update()
{
if(condition)
{
throw new Exception("..."); // Prevent derived method to be called
}
}
}
Y luego en una clase derivada:
public override void Update()
{
base.Update(); // Forced call
// Do any work
}
Busqué y encontré una sugerencia para usar una actualización no virtual () pero también una actualización virtual protegida (). Simplemente no se siente muy ordenado, ¿no hay alguna otra manera mejor?
Espero que entiendas la pregunta y lo siento por cualquier mal inglés.
Creo que tener un miembro base no virtual que llama un "gancho" virtual que se puede extender es la solución más común para este tipo de problema.
Dependiendo de su caso de uso, quizás desee utilizar un event
, pero el patrón habitual para implementar un evento es tener un método virtual OnEvent
que las subclases puedan anular en lugar de agregar un controlador de eventos, por lo que en su caso de ejemplo, se reduce a la misma cosa.
Utilice el patrón de método de la plantilla : no anule el método base que necesita hacer algún trabajo, anule un bit específico, que puede ser abstracto o no operativo en la clase base. (La decisión acerca de si es un resumen no operativo o no operativo suele ser bastante obvia: ¿la clase base tiene sentido por sí misma, como una clase concreta?)
Parece que este es básicamente el patrón que has encontrado con UpdateEx
, aunque generalmente es UpdateImpl
o algo similar en mi experiencia. No hay nada de malo en esto como un patrón, en mi opinión, evita cualquier idea de forzar a todas las clases derivadas a escribir el mismo código para llamar al método base.
Esto me llevó un poco obtener lo que se vería con Update y UpdateEx. Aquí hay un ejemplo de código que podría ayudar a otros.
public class BaseClass
{
// This is the Update that class instances will use, it''s never overridden by a subclass
public void Update()
{
if(condition);
// etc... base class code that will always run
UpdateEx(); // ensure subclass Update() functionality is run
}
protected virtual void UpdateEx()
{
// does nothing unless sub-class overrides
}
}
Una subclase nunca tendrá implementación para Update (). Utilizará UpdateEx () para agregar implementación a Update ();
public class ConcreteClass : BaseClass
{
protected override void UpdateEx()
{
// implementation to be added to the BaseClass Update();
}
}
Cualquier instancia de ConcreteClass utilizará la implementación de BaseClass de Update () junto con ConcreteClass pero lo extiende con UpdateEx ().