Base Constructor se llama en primer lugar. Pero el inicializador de campos en la clase derivada se llama primero.
10.11.3 Constructor
inicializadores de variables se transforman en instrucciones de asignación, y estas asignación instrucciones se ejecutan antes de la invocación de la instancia de constructor de la clase de base . Este orden garantiza que todos los campos de instancia se inicialicen mediante sus inicializadores de variable antes de que se ejecuten las sentencias que tienen acceso a esa instancia. Dado el ejemplo
using System;
class A
{
public A() {
PrintFields();
}
public virtual void PrintFields() {}
}
class B: A
{
int x = 1;
int y;
public B() {
y = -1;
}
public override void PrintFields() {
Console.WriteLine("x = {0}, y = {1}", x, y);
}
}
Cuando se utiliza new B()
para crear una instancia de B
, la siguiente salida se produce:
x = 1, y = 0
El valor de x
es 1 porque el inicializador variable se ejecuta antes de la Se invoca el constructor de instancia de la clase base. Sin embargo, el valor de y
es 0 (el valor predeterminado de int
) porque la asignación a y
no se ejecuta hasta que devuelve el constructor de la clase base. Es útil pensar en los inicializadores de variables de instancia y los inicializadores de constructor como enunciados que se insertan automáticamente en antes del cuerpo del constructor. El ejemplo
using System;
using System.Collections;
class A
{
int x = 1, y = -1, count;
public A() {
count = 0;
}
public A(int n) {
count = n;
}
}
class B: A
{
double sqrt2 = Math.Sqrt(2.0);
ArrayList items = new ArrayList(100);
int max;
public B(): this(100) {
items.Add("default");
}
public B(int n): base(n – 1) {
max = n;
}
}
contiene varios inicializadores variables; también contiene los inicializadores del constructor de ambas formas (base y esto). El ejemplo corresponde a el código que se muestra a continuación, donde cada comentario indica una instrucción insertada automáticamente (la sintaxis utilizada para las invocaciones de constructor automáticamente insertadas no es válida, pero sirve simplemente para ilustrar el mecanismo).
using System.Collections;
class A
{
int x, y, count;
public A() {
x = 1; // Variable initializer
y = -1; // Variable initializer
object(); // Invoke object() constructor
count = 0;
}
public A(int n) {
x = 1; // Variable initializer
y = -1; // Variable initializer
object(); // Invoke object() constructor
count = n;
}
}
class B: A
{
double sqrt2;
ArrayList items;
int max;
public B(): this(100) {
B(100); // Invoke B(int) constructor
items.Add("default");
}
public B(int n): base(n – 1) {
sqrt2 = Math.Sqrt(2.0); // Variable initializer
items = new ArrayList(100); // Variable initializer
A(n – 1); // Invoke A(int) constructor
max = n;
}
}
Tienes razón. Pero la ejecución comienza en el constructor derivado, lo primero que hace el constructor derivado es llamar al constructor base (si hay alguno). Por lo tanto, parece que se está llamando primero al constructor base. –