2010-08-01 3 views
3

Quelle est la différence entre celle-ci:Quelle est la différence entre l'instanciation dans le constructeur ou dans la définition de champ?

public class Foo { 
    private Bar bar; 
    public Foo() { bar = new Bar(); } 
} 

et ceci:

public class Foo { 
    private Bar bar = new Bar(); 
    public Foo() { } 
} 
+0

http://stackoverflow.com/questions/24551/best-practice-initialize-class-fields-in-constructor-or-at-declaration – SwDevMan81

+0

http://stackoverflow.com/questions/1157201/initializing-class -fields-at-the-field-definition-ou-in-class-contructor – SwDevMan81

Répondre

9

La différence est que, dans la seconde initialisation cas de champ se produit avant que ce/constructeur de base tandis que dans la première initialisation cas se produit à l'intérieur le constructeur.

+0

Est-ce juste une question technique ou existe-t-il des raisons pratiques de favoriser une approche ou une autre? Par exemple, si au lieu d'un 'Bar', j'ai utilisé un type de contexte de données (par exemple à partir de framework d'entité), existe-t-il une différence pratique? – guhou

+2

@ BlueM937 si vous avez plusieurs constructeurs alors vous pouvez dupliquer du code –

1

En indiquant l'un peu évident, mais avec la deuxième approche, il n'y a pas besoin d'un constructeur.

0

Il n'y a pas de différence, car un compilateur place toutes les définitions de champs avant le code du constructeur. Donc, dans le code IL, les deux variantes ont la même apparence.

6

Le CLR ne prend pas en charge l'initialisation de champs de ce type. Pour le faire fonctionner, le compilateur C# réécrit votre constructeur. L'IL ressemble à ceci:

IL_0000: ldarg.0 
    IL_0001: newobj  instance void ConsoleApplication1.Bar::.ctor() 
    IL_0006: stfld  class ConsoleApplication1.Bar ConsoleApplication1.Foo::bar 
    IL_000b: ldarg.0 
    IL_000c: call  instance void [mscorlib]System.Object::.ctor() 
    IL_0011: ret 

Notez que le constructeur est appelé Bar avant le constructeur de base Foo. Quelle est la différence avec votre autre extrait, là le constructeur de base Foo est appelé par la suite. Cela fera rarement une différence, sauf si le champ est hérité et le constructeur de la classe de base fait quelque chose avec lui.

Ou si les initialiseurs de champ dépendent les uns des autres, ils sont initialisés dans un ordre textuel strict. Vous pouvez contrôler l'ordre en le faisant explicitement dans le constructeur.

0

Pour ajouter à la réponse de Darin Dimitrov, initialiser les champs en ligne est une bonne idée si vous avez plusieurs surcharges de constructeur, et vous ne voulez pas appeler d'autres constructeurs surchargés pour une raison quelconque.

Questions connexes