2011-09-28 21 views

Respuesta

3

Es absolutamente una buena práctica por dos razones principales:

Para evitar la duplicación de código

class Foo 
{ 
    public Foo(String myString, Int32 myInt){ 
     //Some Initialization stuff here 
    } 

    //Default value for myInt 
    public Foo(String myString) : this(myString, 42){} 

    //Default value for both 
    public Foo() : this("The Answer", 42){} 
} 

Para establecer buenas encapsulación

public abstract class Foo 
{ 
    protected Foo(String someString) 
    { 
     //Important Stuff Here 
    } 
} 

public class Bar : Foo 
{ 
    public Bar(String someString, Int32 myInt): base(someString) 
    { 
     //Let's the base class do it's thing 
     // while extending behavior 
    } 
} 
+0

Cualquier comentario sobre por qué es sólo está disponible para los constructores? ¿Por qué no puedo usar la misma técnica con otros métodos sobrecargados? –

2

La razón principal es poder reutilizar el código entre los constructores. En lugar de duplicar la inicialización, puede poner todo el código de inicialización en un único constructor y llamarlo desde otros constructores.

0

Lo he visto cuando se realizan trabajos pesados ​​en el momento de la construcción, y hay muchas maneras diferentes de crear el objeto. (Tan solo un puñado de ctors con diferentes firmas de parámetros).

Puede tener solo una función de miembro privado que haga el trabajo común en todos los ctors. Realmente no necesita tener un ctor llamar a otro en la misma clase. (Que ni siquiera está permitido en la mayoría de los idiomas).

1

'Constructor encadenamiento' es una enfoque por el cual un constructor llama a otro constructor en la misma cla ss. Esto es particularmente útil cuando tenemos una clase que define múltiples constructores. Por ejemplo, estamos creando una clase llamada Persona en el siguiente ejemplo. También tenemos tres campos que podemos usar; Edad, Nombre y HairColour. Esta clase tiene tres constructores. Si no usamos el enfoque de 'Constructor de encadenamiento', el código sería algo así como a continuación:

No utilizar Constructor en cadena:

public class Person 
    { 
     private int Age; 
     private string Name; 
     private string HairColour; 


     public Person(int theAge) 
     { 
      Age = theAge; 
     } 

     public Person(int theAge, string theName) 
     { 
      Age = theAge; 
      Name = theName; 
     } 

     public Person(int theAge, string theName, string theHairColour) 
     { 
      Age = theAge; 
      Name = theName; 
      HairColour = theHairColour; 
     } 

    } 

Como se puede ver, en cada constructor estamos asignando una valor a Age, que duplica el código. También hemos asignado un valor a Name en dos de los constructores, por lo que una vez más duplicación. Para eliminar este problema, podemos asignar todos los valores a Age, Name y HairColour en el constructor con la mayoría de los parámetros. Entonces podemos llamar a ese constructor cuando se llaman los otros dos constructores. Vea el código a continuación para ver este enfoque de "Encadenamiento".

Usando Constructor en cadena:

public class Person 
    { 
     private int Age; 
     private string Name; 
     private string HairColour; 


     public Person(int theAge):this(theAge, "", "") 
     { 
      //One parameter 
     } 

     public Person(int theAge, string theName):this(theAge, theName, "") 
     { 
      //Two Parameters 
     } 

     public Person(int theAge, string theName, string theHairColour) 
     { 
      //Three parameters 
      Age = theAge; 
      Name = theName; 
      HairColour = theHairColour; 
     } 

    } 

Espero que ayude - se ahorra en la duplicación.

Un ejemplo más 'extremo' con una gran cantidad de campos (y por lo tanto una gran cantidad de posibles duplicaciones) se muestra aquí:

An example where it will definitely save on duplication

+1

Para mantener el comportamiento exactamente igual, tendría que pasar 'null' en lugar de' "' 'a los constructores encadenados –

Cuestiones relacionadas