2009-03-26 23 views
5

Cuando empecé a trabajar con lenguajes de programación orientados a objetos, me enseñaron la siguiente regla:¿Por qué se deben inicializar las variables miembro en los constructores?

Cuando se declara un campo de una clase, no inicializar todavía. Haz eso en el constructor.

Un ejemplo en C#:

public class Test 
{ 
    private List<String> l; 

    public Test() 
    { 
     l = new List<String>(); 
    } 
} 

Pero cuando alguien me preguntó recientemente por qué hacer eso, no pude llegar a una razón. No estoy realmente familiarizado con el funcionamiento interno de C# (u otros lenguajes de programación, para el caso, ya que creo que esto se puede hacer en todos los lenguajes OO).

¿Por qué es esto hecho? ¿Es seguridad? Propiedades?

Respuesta

14
  • Si tiene varios constructores, es posible que desee inicializar un campo para diferentes valores

  • Al inicializar el campo en el constructor, no puede haber confusión sobre el momento exacto en que se inicia en lo que se refiere al resto del constructor. Esto puede parecer trivial con una sola clase, pero no tanto cuando tiene una jerarquía de herencia con código de constructor ejecutándose en cada nivel y accediendo a los campos de superclase.

10

El compilador de C# tomará cualquier inicialización de miembro no estático que realice en línea y lo moverá al constructor por usted. En otras palabras esto:

class Test 
{ 
    Object o = new Object(); 
} 

se compila a esto:

class Test 
{ 
    Object o; 

    public Test() 
    { 
     this.o = new Object(); 
    } 
} 

No estoy seguro de cómo compiladores para otros idiomas manejan esto pero en lo que se refiere a C# es una cuestión de estilo y se son libres de hacer lo que desee. Tenga en cuenta que los campos estáticos se manejan de manera diferente:read this article for more information on that.

1

veces el constructor tiene parámetros que se utilizan para inicializar variables internas. Por ejemplo, el tamaño de las matrices

2

Una razón para hacerlo es que pone todo el código de inicialización en un lugar que es conveniente para los demás que leen su clase. Habiendo dicho esto, realmente no lo hago por dos razones principales. (1) Utilizo la prueba TDD/Unit para definir el comportamiento de mi clase. Si quieres saber qué hace el constructor sin parámetros, realmente deberías leer las pruebas que he creado en el constructor sin parámetros. (2) Con C# 3.0, normalmente utilizo propiedades automáticas e inicialización en línea con un constructor sin parámetros para instanciar el objeto. Esto es mucho más flexible y pone la definición de las propiedades en línea donde se usa el código. Esto anularía cualquier inicialización en el constructor, así que rara vez pongo allí. Por supuesto, esto solo se aplica a C#.

Ej. (de 2)

var foo = new Foo { Bar = "baz" }; 

    public class Foo 
    { 
     public string Bar { get; set; } 

     public Foo() { } 
    } 
0

No he oído una razón convincente para no ofrecer ambas opciones. Sospecho que la razón real tiene que ver con la simplificación de la estructura del lenguaje desde una perspectiva de análisis.Esto es especialmente cierto en los lenguajes de derivadas C donde el análisis de una declaración de asignación requiere el 75% de las reglas de sintaxis del lenguaje. Me parece que permitirlo y definir cómo funcionaría exactamente sería bueno. Estoy de acuerdo con Michael's comment sobre el aumento de la complejidad a medida que insertas la herencia y múltiples constructores, pero solo porque agregas una característica no significa que tengas que usarla. Yo votaría para apoyar a ambos a pesar de que mi voto realmente no suma mucho.

0

Siempre me gusta pensar en la clase como una fábrica de objetos, y el constructor como la parada final en la línea de producción. Los campos declarados en la clase son planos que delimitan el objeto, pero el plano no se realizará en un objeto antes de ordenar tal objeto a través de una llamada al constructor ... Además, como alguien señaló, haciendo todas las inicializaciones en tu constructor mejorará la legibilidad, así como también proporcionará dinámica en la inicialización (puede que no sea un constructor sin parámetros con el que estés tratando).

Además, en algunos idiomas el constructor se puede usar para restablecer un objeto a un estado original, por lo que será necesario instalar el objeto en el constructor.

Cuestiones relacionadas