Es conveniente evitar en la medida
de lo posible la realización de llamadas a métodos virtuales dentro de los
constructores, ya que ello puede provocar errores muy difíciles de detectar
debido a que se ejecuten métodos cuando la parte del objeto que manipulan aún
no se ha sido inicializado. Un ejemplo de esto es el siguiente:
using System;
public class Base
{
public Base()
{
Console.WriteLine("Constructor
de Base");
this.F();
}
public
virtual void F()
{
Console.WriteLine("Base.F");
}
}
public class
Derivada:Base
{
Derivada()
{
Console.WriteLine("Constructor
de Derivada");
}
public
override void F()
{
Console.WriteLine("Derivada.F()");
}
public
static void Main()
{
Base b = new Derivada();
}
}
La salida por pantalla mostrada
por este programa al ejecutarse es la siguiente:
Constructor de Base
Derivada.F()
Constructor de Derivada
Lo que ha ocurrido es lo
siguiente: Al crearse el objeto Derivada se
ha llamado a su constructor sin parámetros, que como no tiene inicializador
implícitamente llama al constructor sin parámetros de su clase base. El
constructor de Base realiza
una llamada al método virtual F(), y
como el verdadero tipo del objeto que se está contruyendo es Derivada, entonces versión del método virtual
ejecutada es la redefinición del mismo incluida en dicha clase. Por último, se
termina llamando al constructor de Derivada y
finaliza la construcción del objeto.
Nótese que se ha ejecutado el
método F() de Derivada antes que el código del constructor de dicha
clase, por lo que si ese método manipulase campos definidos en Derivada que se inicializasen a través de
constructor, se habría accedido a ellos antes de inicializarlos y ello
seguramente provocaría errores de causas difíciles de averiguar.