2008-08-20 15 views
44

En C#, si tengo una clase heredada con un constructor predeterminado, ¿tengo que llamar explícitamente al constructor de la clase base o se llamará implícitamente?En C#, ¿necesita llamar al constructor base?

class BaseClass 
{ 
    public BaseClass() 
    { 
     // ... some code 
    } 
} 
class MyClass : BaseClass 
{ 
    public MyClass() // Do I need to put ": base()" here or is it implied? 
    { 
     // ... some code 
    } 
} 

Respuesta

49

No necesita llamar explícitamente al constructor base, se llamará implícitamente.

ampliar su ejemplo un poco y crear una aplicación de consola y se puede comprobar este comportamiento por sí mismo:

using System; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      MyClass foo = new MyClass(); 

      Console.ReadLine(); 
     } 
    } 

    class BaseClass 
    { 
     public BaseClass() 
     { 
      Console.WriteLine("BaseClass constructor called."); 
     } 
    } 

    class MyClass : BaseClass 
    { 
     public MyClass() 
     { 
      Console.WriteLine("MyClass constructor called."); 
     } 
    } 
} 
0

AFAIK, solo necesita llamar al constructor base si necesita transmitirle cualquier valor.

6

Está implícito.

+0

Esto es correcto, porque el OP indicó el "constructor predeterminado (aka parameterless)". –

4

Una clase derivada se basa en la clase base. Si lo piensas, el objeto base debe crearse una instancia en la memoria antes de que la clase derivada se pueda agregar a él. Por lo tanto, el objeto base se creará en el camino para crear el objeto derivado. Entonces no, no llamas al constructor.

23

Está implícito, siempre que no tenga parámetros. Esto se debe a que necesario implementar constructores que toman valores, ve el código de abajo para ver un ejemplo:

public class SuperClassEmptyCtor 
{ 
    public SuperClassEmptyCtor() 
    { 
     // Default Ctor 
    } 
} 

public class SubClassA : SuperClassEmptyCtor 
{ 
    // No Ctor's this is fine since we have 
    // a default (empty ctor in the base) 
} 

public class SuperClassCtor 
{ 
    public SuperClassCtor(string value) 
    { 
     // Default Ctor 
    } 
} 

public class SubClassB : SuperClassCtor 
{ 
    // This fails because we need to satisfy 
    // the ctor for the base class. 
} 

public class SubClassC : SuperClassCtor 
{ 
    public SubClassC(string value) : base(value) 
    { 
     // make it easy and pipe the params 
     // straight to the base! 
    } 
} 
7

Queda implícito para los constructores sin parámetros de base, pero es necesario para que por defecto en la clase actual:

public class BaseClass { 
    protected string X; 

    public BaseClass() { 
     this.X = "Foo"; 
    } 
} 

public class MyClass : BaseClass 
{ 
    public MyClass() 
     // no ref to base needed 
    { 
     // initialise stuff 
     this.X = "bar"; 
    } 

    public MyClass(int param1, string param2) 
     :this() // This is needed to hit the parameterless ..ctor 
    { 
     // this.X will be "bar" 
    } 

    public MyClass(string param1, int param2) 
     // :base() // can be implied 
    { 
     // this.X will be "foo" 
    } 
} 
+0

Un poco viejo para estar seguro, pero en caso de que alguien tropiece con esto. Tenga en cuenta que en el constructor sobrecargado, el orden de las llamadas será en realidad: base() -> MyClass() -> MyClass (int param1, string param2). Su comentario al lado de "this()" parecía algo engañoso, ya que si se agrega this() evitaría que la llamada creara una instancia de la clase base. – Wrightboy

+0

@Wrightboy sí, ese es el orden correcto en el que se llamará a los constructores. Lo que quiero decir es que no está implícito: puedes especificar explícitamente 'this()' o 'base()', pero si no lo haces, ninguno será llamado. – Keith

+0

'base()' siempre se llama. 'public MyClass (int param1, string param2)' y 'public MyClass (int param1, string param2): base()' son equivalentes. El 'this()' solo agrega una llamada adicional después de la llamada 'base()' pero antes de sí misma. – Wrightboy

-3

no es necesario llamar al constructor de base de forma explícita que se llamará de forma implícita, pero a veces es necesario pasar parámetros al constructor en ese caso se puede hacer algo como:

using System; 
namespace StackOverflow.Examples 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      NewClass foo = new NewClass("parameter1","parameter2"); 
      Console.WriteLine(foo.GetUpperParameter()); 
      Console.ReadKey(); 
     } 
    } 

    interface IClass 
    { 
     string GetUpperParameter(); 
    } 

    class BaseClass : IClass 
    { 
     private string parameter; 
     public BaseClass (string someParameter) 
     { 
      this.parameter = someParameter; 
     } 

     public string GetUpperParameter() 
     { 
      return this.parameter.ToUpper(); 
     } 
    } 

    class NewClass : IClass 
    { 
     private BaseClass internalClass; 
     private string newParameter; 

     public NewClass (string someParameter, string newParameter) 
     { 
      this.internalClass = new BaseClass(someParameter); 
      this.newParameter = newParameter; 
     } 

     public string GetUpperParameter() 
     { 
      return this.internalClass.GetUpperParameter() + this.newParameter.ToUpper(); 
     } 
    } 
} 

Nota: Si alguien conoce una solución mejor, por favor, dígame.

+2

Parece que alguien necesita una lección de composición vs herencia. ;) –

Cuestiones relacionadas