2010-07-01 4 views
2

J'essaie d'utiliser des initialiseurs d'objet pour définir les propriétés d'une classe et y accéder ensuite dans le constructeur de la classe. Le problème est que les propriétés ne semblent pas être définies avant l'exécution du constructeur. Est-ce que je fais quelque chose de mal.Initialisateurs d'objet et constructeurs

classe de base ..

public class TestClass 
{ 
    public string FirstName{get; set;} 

    public TestClass(){ 
     NewClass nc = NewClass(FirstName); 
    } 

} 

classe client

public class ClientClass 
{ 
    public ClientClass(){ 
     TestClass tc = new TestClass{ FirstName="Jimmy"}; 
    } 
} 

Répondre

10

Les initialiseurs d'objet sont vraiment du sucre syntaxique. Étant donné:

var person = new Person() { Name = "Matt" }; 

Le compilateur va changer cela:

Person person = new Person(); 
person.Name = "Matt"; 

(bien, en fait sa variante IL)

Le constructeur sera toujours exécuté avant des ensembles de propriétés. Il est très important lors de la création d'un constructeur que vous passez dans tous les paramètres sont nécessaires pour initialiser correctement votre type. Dans votre exemple, vous avez besoin de Prénom, alors pourquoi ne pas le passer en paramètre constructeur?

public TestClass(string firstName) { } 
0

Non, vous ne faites rien de mal. C'est ainsi que fonctionnent les initialiseurs d'objets. Ils appellent le constructeur en premier pour obtenir une référence à l'objet et seulement après avoir défini les propriétés. C'est juste du sucre syntaxique.

1
TestClass tc = new TestClass { FirstName = "Jimmy" }; 

est le sucre syntaxique pour

TestClass tc = new TestClass(); 

tc.FirstName = "Jimmy"; 

et donc le résultat attendu est ce que vous observez - les propriétés sont attribuées après le constructeur exécuté.

Les invariants d'objet devraient être établis par le constructeur et ne pas être violés pendant la durée de vie de l'objet (ou plus les violations invariantes pratiques devraient être de courte durée et non visibles au monde extérieur). Par conséquent, vous devriez vraiment passer le prénom en tant que paramètre constructeur s'il est important pour établir des invariants d'objet. À mon avis, les initialiseurs de champ sont fortement surutilisés. Gardez toujours à l'esprit que vous pouvez forcer l'appelant à fournir des arguments constructeurs mais ne pas définir certaines propriétés après la construction d'une nouvelle instance.

0

Tout comme les autres réponses ont dit. Ce que vous pouvez faire est d'utiliser un constructeur pour définir le Prénom:

public TestClass(string firstName){ 
    FirstName = firstName; 
    NewClass nc = NewClass(FirstName); 
}