2011-07-17 9 views
19

Esto es fácil de solucionar, pero tengo curiosidad si podría utilizar una función de idioma o posiblemente el hecho de que el lenguaje no lo permita significa que estoy cometiendo un error lógico en el diseño de clase.¿cómo llamo a los inicializadores de constructor, base() y this()?

estoy haciendo una revisión auto de mi código para ayudar a "endurecer" que para su reutilización y me acaba de llegar al otro lado:

public partial class TrackTyped : Component 
{ 
    IContainer components = null; 

    public TrackTyped() 
     : base() 
    { 
     InitializeComponent(); 
    } 

    public TrackTyped(IContainer container) 
     : base() 
    { 
     container.Add(this); 
     InitializeComponent(); 
    } 
} 

lo que suelo hacer cuando veo la misma línea de código en dos constructores hacen una llamada la otra con "this()" pero parece que no puedo hacerlo.

Si leo el derecho de especificaciones (acabo de empezar tratando de leer la especificación, así que puede no ser adecuado):

10.11 Instance Constructors 
    constructor-declarator: 
     identifier ( formal-parameter-listopt ) constructor-initializeropt 
    constructor-initializer: 
     : base ( argument-listopt ) 
     : this ( argument-listopt ) 

Es como decir que sólo puedo tener uno de esos.

PREGUNTA: ¿es 10.11 lo que implica que no hay razón para necesitar llamar a ambos o simplemente está implicando que el lenguaje solo admite llamar a uno?

+0

Gracias a TODOS por la respuesta (obvio ahora, no tan obvio para mí hace un momento) :) –

+0

no, simplemente no pensé en la respuesta por alguna razón, no creo en el contenedor.Añadir (esto) tiene que suceder antes de InitializeComponent() - y si lo hiciera probablemente me preguntaría si eso fue un signo de diseño extraño. –

+0

en el ejemplo, "new TrackedType()" primero se ejecuta, luego .Add(). Personalmente, me parece más claro de esa manera. Téngalo en cuenta para más tarde quizás. – sgtz

Respuesta

16

No hay necesidad de llamar a ambos, porque this redirige a otro constructor que llamará al base.

2

es esto lo que estás buscando?

public partial class TrackTyped : Component 
{ 
    IContainer components = null; 
    public TrackTyped() : base() 
    { 
     // logic for InitializeComponent() here 
    } 

    public TrackTyped(IContainer container) : this() 
    { 
     container.Add(this) 
    } 
} 

por cierto: eso es un uso interesante para el segundo ctor:

var a = TrackTyped(container); 

Me pregunto si la supresión de la segunda ctor y haciendo esto se quedaría más claro para usted? (el mismo resultado final)

container.Add(new TrackTyped()); 
+0

usted hace un buen punto, así que profundicé un nivel más y descubrí que el razonamiento era hacer que mi componente fuera utilizable con el diseñador de Winforms, que automáticamente agregará una línea a la rutina de inicialización del componente contenedor como así: this.trackTypedTextComponent1 = new EomApp1. Components.TrackTyped (this.components); –

7

Usted no y no puede. Puede reenviar la llamada de constructor a otro constructor de la misma clase al :this(...). El último constructor en esa cadena tendrá que inicializar la base implícita o explícitamente por :base(...)

Supongamos que la clase A tiene dos constructores. Uno inicializa la base con :base(2), el otro con :base(3). Si al primer constructor se le permitió especificar también :this (/*call the other ctor*/), ¿cómo debe haberse inicializado la base: con 2 o 3? Es por eso que estas cosas no se permiten

7

Esto parece ser lo que quiere:

public partial class TrackTyped : Component 
{ 
    IContainer components = null; 

    public TrackTyped() 
     : base() 
    { 
     InitializeComponent(); 
    } 

    public TrackTyped(IContainer container) 
     : this() 
    { 
     container.Add(this); 
    } 
} 

El orden de las declaraciones en el segundo constructor es diferente ahora, sin embargo. Si eso es importante, entonces no hay realmente una buena manera de hacer lo que quiera, ya que aunque tenga la misma línea , la funcionalidad es sutilmente diferente. En ese caso, solo tendrá que repetir la línea individual. No te preocupes

Y está leyendo las especificaciones correctamente: tiene que ser una o la otra.

Cuestiones relacionadas