2009-04-15 22 views
7

Tengo algunos tipos que se derivan de simplificado Base como se muestra a continuación.¿Constructor de "base" de sobrecarga o "este" constructor?

No estoy seguro de si usar el constructor de la clase base o el constructor this al sobrecargar constructores.

ConcreteA sobrecargas constructores puramente usando base constructores, mientras
ConcreteB sobrecargas usando this para los dos primeros sobrecargas.

¿Cuál sería una mejor forma de sobrecargar constructores?

public abstract class Base 
{ 
    public string Name { get; set; } 
    public int? Age { get; set; } 

    protected Base() : this(string.Empty) {} 
    protected Base(string name) : this(name, null) {} 
    protected Base(string name, int? age) 
    { 
     Name = name; 
     Age = age; 
    } 
} 

public class ConcreteA : Base 
{ 
    public ConcreteA(){} 
    public ConcreteA(string name) : base(name) {} 
    public ConcreteA(string name, int? age) : base(name, age) 
    { 
    } 
} 

public class ConcreteB : Base 
{ 
    public ConcreteB() : this(string.Empty, null){} 
    public ConcreteB(string name): this(name, null){} 
    public ConcreteB(string name, int? age) : base(name, age) 
    { 
    } 
} 

[Editar] Parece que lo que Ian Quigley ha sugerido en su answer parecía tener sentido. Si recibiera una llamada que inicialice los validadores, ConcreteA(string) nunca inicializará los validadores en el siguiente caso.

public class ConcreteA : Base 
{ 
    public ConcreteA(){} 
    public ConcreteA(string name) : base(name) {} 
    public ConcreteA(string name, int? age) : base(name, age) 
    { 
     InitializeValidators(); 
    } 
    private void InitializeValidators() {} 
} 

Respuesta

5

Este. Porque si alguna vez colocas el código en ConcreteB (string, int?), Entonces quieres que el constructor de cadenas solo lo llame.

+0

Esto parece tener sentido si tuviera que realizar otras inicializaciones en constructores de hormigón. – Sung

+0

Sí, y "esto" siempre llamará "base" al final del día. Entonces, incluso si "esto" no hace nada, se reducirá a "base" –

1

En su caso por lo que ha proporcionado, no importa. En realidad, solo desea utilizar this cuando tiene un constructor en su clase actual que no es parte de su clase base, o si hay algún código en el constructor de clase actual que desea ejecutar que no está contenido en la clase base .

2

En general, yo llamaría "esto" en lugar de "base". Probablemente reutilizará más código de esa manera, si expande sus clases más adelante.

0

Para reducir la complejidad de las rutas de código, generalmente intento tener exactamente una llamada de constructor base() (el caso ConcreteB). De esta forma sabrá que la inicialización de la clase base siempre ocurre de la misma manera.

Sin embargo, dependiendo de la clase que anule, esto puede no ser posible o agregar complejidad innecesaria. Esto es válido para patrones de constructor especiales como el que se implementa al implementar ISerializable.

2

Está bien mezclar y combinar; finalmente, cuando utiliza un constructor this(...), eventualmente llega a un ctor que llama primero al base(...). Tiene sentido reutilizar la lógica cuando sea necesario.

Puede organizarlo de modo que todos los constructores llamen a un constructor this(...) común (tal vez privado) que es el único que llama al base(...) - pero eso depende de si a: es útil hacerlo, y b : si hay un solo base(...) ctor que le permita.

0

Pregúntese de nuevo por qué está sobrecargando el constructor en la clase Base? Éste es suficiente:

protected Base() 

Lo mismo sucede con la subclase a menos que necesite cualquiera de los campos que tienen un valor particular cuando se instancia la que en su ejemplo no es el caso, puesto que ya tiene el constructor por defecto.

Recuerde también que cualquier constructor debe colocar la instancia del objeto en un estado correcto.

Cuestiones relacionadas