70 votos

C# miembro de inicialización de la variable; la mejor práctica?

Es mejor para inicializar las variables miembro de clase en la declaración

private List<Thing> _things = new List<Thing>();
private int _arb = 99;

o en el constructor por defecto?

private List<Thing> _things;
private int _arb;

public TheClass()
{
  _things = new List<Thing>();
  _arb = 99;
}

Es simplemente una cuestión de estilo o no rendimiento de los trade-offs, de una manera o de la otra?

59voto

Marc Gravell Puntos 482669

En términos de rendimiento, no hay ninguna diferencia real; campo de inicializadores se implementan como constructor de la lógica. La única diferencia es que el campo de inicializadores de suceder antes de que cualquier "base"/"este" constructor.

El constructor de enfoque puede ser utilizado con propiedades de implementación automática (campo de inicializadores no) - es decir,

[DefaultValue("")]
public string Foo {get;set;}
public Bar() { // ctor
  Foo = "";
}

Aparte de eso, tiendo a preferir el campo de inicializador de la sintaxis, creo que mantiene las cosas localizada - es decir,

private readonly List<SomeClass> items = new List<SomeClass>();
public List<SomeClass> Items {get {return items;}}

No tengo que ir a la caza de arriba y abajo para encontrar donde es asignado...

La excepción obvia es donde usted necesita para realizar la compleja lógica o de acuerdo con los parámetros del constructor - en cuyo caso constructor basado en la inicialización es el camino a seguir. Del mismo modo, si usted tiene varios constructores, sería preferible para los campos, para que siempre obtenga de la misma manera - por lo que podría tener ctors como:

public Bar() : this("") {}
public Bar(string foo) {Foo = foo;}

edit: como un comentario, nota que en el anterior, si hay otros campos (no se muestra) con un campo de inicializadores, que luego son directamente sólo se inicializa en la clasificación de constructores que llame base(...) - es decir, la public Bar(string foo) cto r. El otro constructor que hace que no se ejecute el campo de inicializadores, ya que se sabe que son realizados por el this(...) cto r.

7voto

Tor Haugen Puntos 8258

En realidad, el campo de inicializadores como usted demuestra es una forma abreviada conveniente. El compilador copia el código de inicialización en el comienzo de cada constructor de instancia que defina para su tipo.

Esto tiene dos implicaciones: en primer lugar, cualquier campo de código de inicialización se duplica en cada constructor y, en segundo lugar, cualquier código que se va a incluir en su constructores para inicializar los campos con valores específicos en el hecho de re-asignar los campos.

Así que en cuanto al rendimiento, y con respecto al código compilado tamaño, es mejor mover el campo inicializadores en constructores.

Por otro lado, el impacto en el rendimiento y el código de 'inflar' usualmente se negligable, y el campo de inicializador de sintaxis tiene la importante ventaja de disminuir el riesgo de que puede que se olvide de inicializar algunas de campo en uno de sus constructores.

3voto

supercat Puntos 25534

Una de las principales limitaciones con campo de inicializadores es que no hay manera de incluirlos en un intento por último bloque. Si se produce una excepción en un campo de inicializador, los recursos que fueron asignados en anteriores inicializadores será abandonado; no hay manera de evitarlo. Otros errores en la construcción puede ser tratada, si torpemente, por haber protegido constructor base aceptar una IDisposable por referencia, y apuntando a sí mismo como su primera operación. Entonces, uno puede evitar llamar al constructor salvo a través de métodos de fábrica que, en el caso de excepción a que se le llame a Disponer en la parte objeto creado. Esta protección se permite para la limpieza de IDisposables creado en la clase derivada inicializadores si el principal constructor de la clase de error después de "contrabando" una referencia al nuevo objeto. Desafortunadamente, no hay manera de brindar esa protección si un campo de inicializador de falla.

1voto

GeekyMonkey Puntos 5036

El uso de cualquiera de los campos inicializadores o crear una función Init (). El problema con poner estas cosas en su constructor es que si alguna vez necesita añadir un 2º constructor, usted termina con copiar/pegar el código (o pasar por alto y terminan con variables no inicializadas).

Yo iba a inicializar donde declarado. O tienen el constructor(s) llamar a una función Init ().

0voto

Kent Boogaart Puntos 97432

Para las variables de instancia, es en gran medida una cuestión de estilo (yo prefiero usar un constructor). Para las variables estáticas, hay un beneficio en el rendimiento para la inicialización de línea (no siempre es posible, por supuesto).

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X