Tentaciones: llamar a this() y base() al mismo tiempo

Como estás muy loco, a veces se te pasa por la cabeza hacer historias descabelladas. Llamar a this() y a base() no se puede, jodío. Aquí lo que tienes que hacer es diseñar los constructores como es debido, no a ciegas, ¡que vas ciego por la vida!

Ejemplo. Tienes una clase Base y otra Derivada.

La clase Derivada tiene un constructor de copia que se basa en un argumento para hacer la copia:

public Derivada(Base toCopyFrom) : base(toCopyFrom)
{
}

Le proporcionamos un objeto del que copiar propiedades. El objeto se lo pasamos a la Base y esta se encarga del resto.

Ahora echamos un ojo al constructor por defecto:

public DynamicTable()
{
	atributoQueNecesitaInicialización = "bla bla bla";
	otroAtributoQueNecesitaInicialización = "bla bla bla";
}

¿Qué ocurre? que si esos atributos necesitan inicializarse, solamente se inicializan llamando al constructor por defecto.

En otro constructor que llama a la base (el de más arriba), los atributos no se inicializan. Puede que tengamos la tentación de modificar el constructor que llama a la base y añadirle esto:

public Derivada(Base toCopyFrom) : base(toCopyFrom), this()
{
}

Pero ¡DÓNDE VAS, LOCO! Eso no puede hacerse y es por una buena razón Pointing up El orden se establece arbitrariamente (primero base, luego this), por lo que si el compilador nos dejara hacer esto, sería una porquerida. Así es que pensamos ¿y si copio las líneas que inicializan las variables también en el otro constructor?

GUARRADA X2!! ¿Duplicar? Chaval, ¡eso es el principio del fin! Nada de duplicar, ¡cojones ya!

Como no somos unos guarretes, decidimos solucionar la papeleta con el estoque fino.

Sencillo, o no tanto:

El constructor por defecto debe llamar al específico con el objeto a null, por ejemplo:

public Derivada() : this(null)
{
}

Aunque lo de meter un null no es una práctica bella (ni aconsejable) lo pongo para que se entienda el concepto. Luego podemos aplicar el patrón NullObject y hacer las comprobaciones necesarias si se trata de ese caso).

De esta manera, el constructor por defecto llama al específico con un null. Finalmente, este constructor específico SÍ llama a la base. Pero además, en él será donde debemos inicializar las variables que teníamos antes. Por lo tanto quedaría así.

public Derivada(Base toCopyFrom) : base(toCopyFrom)
{
	atributoQueNecesitaInicialización = "bla bla bla";
	otroAtributoQueNecesitaInicialización = "bla bla bla";
}

Así, la clase Base construye la copia (le pasamos un nulazo enorme que en estos momento actuaría de indicador. La clase base en este caso debería saber que un null significa un caso especial. Si estamos copiando atributos (constructor de copia) lo más lógico es que no copiara nada.

Si a alguien se le ocurre algo mejor, ¡ahí están los comentarios, muertos de risa! Thinking smile

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s