Est-il préférable d’initialiser des variables de membre de classe sur la déclaration
ou dans le constructeur par défaut ?
Est-ce simplement une question de style ou existe-t-il des compromis performance, un sens ou l’autre ?
Est-il préférable d’initialiser des variables de membre de classe sur la déclaration
ou dans le constructeur par défaut ?
Est-ce simplement une question de style ou existe-t-il des compromis performance, un sens ou l’autre ?
En termes de performances, il n'y a pas de différence réelle; champ initialiseurs sont mis en œuvre en tant que constructeur de la logique. La seule différence est que le champ des initialiseurs d'arriver avant tout "de base"/"ce" constructeur.
Le constructeur approche peut être utilisée avec des propriétés implémentées automatiquement (champ initialiseurs ne peut pas) - c'est à dire
[DefaultValue("")]
public string Foo {get;set;}
public Bar() { // ctor
Foo = "";
}
Autre que cela, j'ai tendance à préférer le domaine de l'initialiseur de la syntaxe; je trouve qu'il garde les choses localisées - à-d.
private readonly List<SomeClass> items = new List<SomeClass>();
public List<SomeClass> Items {get {return items;}}
Je n'ai pas à aller à la chasse en haut et en bas pour trouver où il est affecté...
L'exception, évidemment, est l'endroit où vous avez besoin pour effectuer une logique complexe ou de traiter avec les paramètres du constructeur - le constructeur-en fonction d'initialisation est le chemin à parcourir. De même, si vous disposez de plusieurs constructeurs, il serait préférable pour les champs pour avoir toujours définie de la même manière que vous pourriez avoir ctors comme:
public Bar() : this("") {}
public Bar(string foo) {Foo = foo;}
edit: comme un commentaire, remarque que ci-dessus, si il y a d'autres champs (non illustré) avec le champ des initialiseurs, alors qu'ils ne sont directement initialisé dans le constructeur qui appellent base(...)
- c'est à dire l' public Bar(string foo)
ctor. L'autre constructeur n'a pas de champ exécuter les initialiseurs, car il sait qu'ils sont fait par l' this(...)
ctor.
En fait, le champ des initialiseurs comme vous le démontrer est un raccourci pratique. Le compilateur fait des copies le code d'initialisation au début de chaque instance constructeur que vous définissez pour votre type.
Cela a deux conséquences: d'abord, un champ de code d'initialisation est dupliqué dans chaque constructeur et, d'autre part, tout le code que vous incluez dans votre constructeur pour initialiser les champs de valeurs spécifiques sera en effet re-assigner les champs.
Donc en terme de performance, et en ce qui concerne le code compilé de la taille, vous êtes mieux de déplacer le champ des initialiseurs dans les constructeurs.
D'autre part, l'impact sur les performances et le code 'gonfler' sera généralement négligeable, et que le champ d'initialiseur de syntaxe a l'avantage de diminuer le risque que vous pourriez oublier d'initialiser le terrain, dans l'un de vos constructeurs.
L'une des principales limites du terrain initialiseurs est qu'il n'y a aucun moyen de les envelopper dans un try-finally bloc. Si une exception est levée dans un champ d'initialiseur, toutes les ressources qui ont été allouées dans les précédents initialiseurs sera abandonné; il n'y a aucun moyen de l'empêcher. D'autres erreurs dans la construction peuvent être traitées, si maladroitement, par le fait d'avoir protégé constructeur de base accepter une IDisposable par référence, et pointant à sa première opération. On peut alors éviter d'appeler le constructeur, sauf par l'intermédiaire de méthodes de fabrique qui, dans des cas d'exception appeler dispose sur la partie objet créé. Cette protection permettra de nettoyage de IDisposables créé en dérivés de la classe des initialiseurs si le principal constructeur de la classe échoue après la "contrebande" une référence à l'objet nouveau. Malheureusement, il n'y a aucun moyen de fournir cette protection si un champ d'initialiseur échoue.
Utiliser soit les initialiseurs de champ ou créer une fonction Init(). Le problème avec ces choses dans votre constructeur de mise, c’est que si vous avez besoin d’ajouter un 2ème constructeur, vous vous retrouvez avec copier/coller le code (ou vous donnent sur elle et fin vers le haut avec des variables non initialisées).
J’ai serait soit initialiser lorsque déclarés. Ou avoir l’initialisation à appeler une fonction Init().
Par exemple, des variables, il est en grande partie une question de style (je préfère utiliser un constructeur). Pour les variables statiques, il y a une performance bénéficier d’initialisation inline (pas toujours possible, bien sûr).
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.