¿Inicializar campos de clase en el constructor o en la declaración?
He estado programando en C# y Java recientemente y tengo curiosidad por saber cuál es el mejor lugar para inicializar los campos de mi clase.
¿Debo hacerlo en la declaración?:
public class Dice
{
private int topFace = 1;
private Random myRand = new Random();
public void Roll()
{
// ......
}
}
o en un constructor?:
public class Dice
{
private int topFace;
private Random myRand;
public Dice()
{
topFace = 1;
myRand = new Random();
}
public void Roll()
{
// .....
}
}
Tengo mucha curiosidad por saber cuál es la mejor práctica para algunos de ustedes, veteranos. Quiero ser coherente y ceñirme a un enfoque.
Mis reglas:
- No inicialice con los valores predeterminados en la declaración ( ,,, …
null
) .false
0
0.0
- Prefiera la inicialización en la declaración si no tiene un parámetro de constructor que cambie el valor del campo.
- Si el valor del campo cambia debido a un parámetro del constructor, coloque la inicialización en los constructores.
- Sea consistente en su práctica (la regla más importante).
En C# no importa. Los dos ejemplos de código que proporciona son completamente equivalentes. En el primer ejemplo, el compilador de C# (¿o es el CLR?) construirá un constructor vacío e inicializará las variables como si estuvieran en el constructor (hay un ligero matiz en esto que Jon Skeet explica en los comentarios a continuación). Si ya existe un constructor, cualquier inicialización "arriba" se moverá a la parte superior del mismo.
En términos de mejores prácticas, el primero es menos propenso a errores que el segundo, ya que alguien podría fácilmente agregar otro constructor y olvidarse de encadenarlo.
Creo que hay una advertencia. Una vez cometí un error de este tipo: dentro de una clase derivada, intenté "inicializar en la declaración" los campos heredados de una clase base abstracta. El resultado fue que existían dos conjuntos de campos, uno es "base" y otro son los recién declarados, y me costó bastante tiempo depurarlo.
La lección: para inicializar campos heredados , lo harías dentro del constructor.
Suponiendo el tipo en su ejemplo, definitivamente prefiera inicializar campos en el constructor. Los casos excepcionales son:
- Campos en clases/métodos estáticos
- Campos escritos como estático/final/et al.
Siempre pienso en el listado de campos en la parte superior de una clase como la tabla de contenido (lo que contiene este documento, no cómo se usa) y el constructor como la introducción. Los métodos, por supuesto, son capítulos.
En Java, un inicializador con declaración significa que el campo siempre se inicializa de la misma manera, independientemente del constructor que se utilice (si tiene más de uno) o de los parámetros de sus constructores (si tienen argumentos), aunque un constructor podría posteriormente cambiar el valor (si no es definitivo). Entonces, usar un inicializador con una declaración sugiere al lector que el valor inicializado es el valor que tiene el campo en todos los casos , independientemente del constructor que se use y de los parámetros pasados a cualquier constructor. Por lo tanto, utilice un inicializador con la declaración sólo si, y siempre si, el valor de todos los objetos construidos es el mismo.