2008-09-26 15 views

Respuesta

92

El constructor base será llamado primero.

Inténtelo:

public class MyBase 
{ 
    public MyBase() 
    { 
    Console.WriteLine("MyBase"); 
    } 
} 

public class MyDerived : MyBase 
{ 
    public MyDerived():base() 
    { 
    Console.WriteLine("MyDerived"); 
    } 
} 
+1

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. –

3

diría base de

EDITAR véase:

http://www.c-sharpcorner.com/UploadFile/rajeshvs/ConsNDestructorsInCS11122005010300AM/ConsNDestructorsInCS.aspx

allí se dice:

using System; 
class Base 
{ 

public Base() 
{ 
    Console.WriteLine("BASE 1"); 
} 
public Base(int x) 
{ 
    Console.WriteLine("BASE 2"); 
} 
} 

class Derived : Base 
{ 
public Derived():base(10) 
{ 
    Console.WriteLine("DERIVED CLASS"); 
} 
} 

class MyClient 
{ 
public static void Main() 
{ 
    Derived d1 = new Derived(); 
} 
} 

salidas Este programa

BASE2

clase derivada

17

En realidad, el constructor de la clase derivada se ejecuta en primer lugar, pero el compilador de C# se inserta una llamada al constructor de la clase base como la primera declaración del constructor derivados .

Entonces: el derivado se ejecuta primero, pero "parece" que la base se ejecutó primero.

+2

Este es uno de esos casos en los que el contexto es importante: en términos CLR, el constructor derivado se ejecuta primero. En términos de C#, el constructor base se ejecuta primero. Hay algunas rarezas como esta donde las especificaciones no concuerdan; por ejemplo, si las estructuras tienen un constructor sin parámetros o no. –

+6

En realidad, parece que hablé demasiado rápido.Ahora he consultado la especificación, y aunque dice que el constructor-inicializador se ejecuta antes que el constructor-cuerpo, eso cuenta como incluido en el constructor general. Así que está totalmente en lo correcto desde ambas perspectivas :) –

127

Los constructores de la clase base reciben una llamada antes que los constructores de clase derivados, pero los inicializadores de clase derivados se llaman antes de los inicializadores de la clase base. P.ej. en el siguiente código:

public class BaseClass { 

    private string sentenceOne = null; // A 

    public BaseClass() { 
     sentenceOne = "The quick brown fox"; // B 
    } 
} 

public class SubClass : BaseClass { 

    private string sentenceTwo = null; // C 

    public SubClass() { 
     sentenceTwo = "jumps over the lazy dog"; // D 
    } 
} 

orden de ejecución es: C, A, B, D.

Salida estos artículos 2 MSDN:

0

Se llamará primero al constructor base, de lo contrario, en los casos en que e sus "otras cosas" deben hacer uso de las variables miembro inicializadas por su constructor base, obtendrá errores de tiempo de compilación porque los miembros de su clase aún no se habrán inicializado.

+0

Las variables miembro no tienen el mismo concepto de asignación definida como variables locales. Ellos tienen un valor predeterminado. Lo interesante de C# es que los inicializadores de variables se ejecutan * antes * del constructor base en lugar de después. (Java tiene el último comportamiento.) –

0

base (?) Se invoca antes de realizar cualquier trabajo en el constructor hijo.

Esto es cierto, incluso si se deja fuera de la: base() (. En cuyo caso, el constructor de base 0-parámetro se denomina)

Funciona de manera similar a Java,

public Child() 
{ 
    super(); // this line is always the first line in a child constructor even if you don't put it there! *** 
} 

*** Excepción: podría ponerme súper (1,2,3) en su lugar. Pero si no puse una llamada a super explícitamente, se llama a super().

+0

Es ligeramente diferente a Java, debido al orden de los inicializadores de variables. Consulte http://pobox.com/~skeet/csharp/constructors.html para obtener detalles. –

+0

Es por eso que utilicé la palabra "similar" –

4

Como han dicho otros, primero se llama al constructor base. Sin embargo, los constructores no son realmente lo primero que sucede.

Digamos que usted tiene clases como esto:

class A {} 

class B : A {} 

class C : B {} 

En primer lugar, serán llamados inicializadores de campo con el fin de más derivada de las clases menos derivada. Entonces primeros inicializadores de campo de C, luego B, luego A.

Los constructores serán llamados en el orden opuesto: Primer constructor de A, luego B, luego C.

0

Las llamadas al constructor se llaman (disparadas) de abajo arriba y se ejecutan de arriba hacia abajo. Por lo tanto, si tenía Clase C que hereda de la Clase B que hereda de la Clase A, cuando crea una instancia de la clase C se llama al constructor para C, que a su vez llama al instructor para B, que a su vez llama al constructor para A. Ahora se ejecuta el constructor para A, luego se ejecuta el constructor para B, luego se ejecuta el constructor para C.

30

No intente recordarlo, intente explicarse lo que debe suceder. Imagina que tienes una clase base llamada Animal y una clase derivada llamada Dog. La clase derivada agrega alguna funcionalidad a la clase base. Por lo tanto, cuando se ejecuta el constructor de la clase derivada, la instancia de la clase base debe estar disponible (para que pueda agregarle nuevas funcionalidades). Es por eso que los constructores se ejecutan desde la base hasta los derivados, pero los destructores se ejecutan de la manera opuesta: primero los destructores derivados y luego los destructores base.

(Esto es simplificada pero debería ayudar a responder a esta pregunta en el futuro sin la necesidad de realidad memorizar esto.)

+4

No lo recuerdo, entiéndelo. Buen trabajo. –

1

Base Constructor se llama en primer lugar. Pero el inicializador de campos en la clase derivada se llama primero.

El orden de llamada es

  1. campo clase derivada inicializador
  2. base de inicializador campo de clase
  3. constructor de la clase de base
  4. clase derivada constructor

(Usted puede tratar 2 y 3 en conjunto para construir la clase base.)

Tomado de CSharp Language Speification 5.0:

ejecución

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; 
    } 
} 
Cuestiones relacionadas