web-dev-qa-db-fra.com

Quelle est la différence entre un initialiseur d'objet et un constructeur?

Quelles sont les différences entre les deux et quand utiliseriez-vous un "initialiseur d'objet" sur un "constructeur" et vice-versa? Je travaille avec C #, si cela compte. En outre, la méthode d'initialisation d'objet est-elle spécifique à C # ou .NET?

159
Pete

Les initialiseurs d’objets ont été ajoutés au C 3, afin de simplifier la construction d’objets lorsque vous utilisez un objet.

Les constructeurs s'exécutent avec 0 ou plusieurs paramètres et sont utilisés pour créer et initialiser un objet avant la méthode appelante récupère le descripteur de l'objet créé. Par exemple:

MyObject myObjectInstance = new MyObject(param1, param2);

Dans ce cas, le constructeur de MyObject sera exécuté avec les valeurs param1 et param2. Ce sont tous deux utilisés pour créer le nouveau MyObject en mémoire. L'objet créé (configuré à l'aide de ces paramètres) est renvoyé et défini sur myObjectInstance.

En général, il est considéré comme une bonne pratique de demander aux constructeurs les paramètres nécessaires pour configurer complètement un objet, de sorte qu'il est impossible de créer un objet dans un état non valide.

Cependant, il existe souvent des propriétés "supplémentaires" qui peuvent être définies, mais ne sont pas obligatoires. Cela pourrait être traité avec des constructeurs surchargés, mais conduit à avoir beaucoup de constructeurs qui ne sont pas nécessairement utiles dans la majorité des cas.

Cela conduit à des initialiseurs d'objet - Un initialiseur d'objet vous permet de définir des propriétés ou des champs sur votre objet après sa construction, mais ) avant , vous pouvez l’utiliser autrement. Par exemple:

MyObject myObjectInstance = new MyObject(param1, param2)
{
    MyProperty = someUsefulValue
};

Cela se comportera de la même manière que si vous agissiez de la sorte:

MyObject myObjectInstance = new MyObject(param1, param2);
myObjectInstance.MyProperty = someUsefulValue;

Cependant, dans les environnements multi-threadés , l'atomicité de l'initialiseur d'objet peut être bénéfique, car elle empêche l'objet de se trouver dans un état non totalement initialisé ( voir cette réponse pour plus de détails) - il est nul ou initialisé comme vous le souhaitiez.

De plus, les initialiseurs d'objet sont plus simples à lire (en particulier lorsque vous définissez plusieurs valeurs), ils offrent donc le même avantage que de nombreuses surcharges sur le constructeur, sans qu'il soit nécessaire que de nombreuses surcharges compliquent l'API pour cette classe.

225
Reed Copsey

Un constructeur est une méthode définie sur un type qui prend un nombre spécifié de paramètres et est utilisé pour créer et initialiser un objet.

Un initialiseur d'objet est un code qui s'exécute sur un objet après un constructeur et peut être utilisé pour définir succinctement un nombre quelconque de champs de l'objet sur des valeurs spécifiées. La configuration de ces champs se produit after le constructeur est appelé.

Vous utiliseriez un constructeur sans l'aide d'un initialiseur d'objet si le constructeur définissait suffisamment l'état initial de l'objet. Un initialiseur d'objet doit cependant être utilisé conjointement avec un constructeur. La syntaxe nécessite l'utilisation explicite ou implicite (VB.Net et C #) d'un constructeur pour créer l'objet initial. Vous utiliseriez un initialiseur d'objet lorsque le constructeur n'initialisait pas suffisamment l'objet à votre utilisation et que quelques champs et/ou ensembles de propriétés simples le feraient.

44
JaredPar

Quand tu fais

Person p = new Person { Name = "a", Age = 23 };

voici ce que fait essentiellement un initialiseur d'objet:

Person tmp = new Person(); //creates temp object calling default constructor
tmp.Name = "a";
tmp.Age = 23;
p = tmp;

Maintenant, cela facilite le comportement comme this . Il est important de savoir comment fonctionnent les initialiseurs d'objet.

27
nawfal

Si vous avez des propriétés qui DOIVENT être définies sur votre objet pour que celui-ci fonctionne correctement, vous pouvez, par exemple, exposer un seul constructeur nécessitant ces propriétés obligatoires en tant que paramètres.

Dans ce cas, vous ne pouvez pas créer votre objet sans spécifier ces propriétés obligatoires. Quelque chose comme ça ne peut pas être imposé par les initialiseurs d'objet.

Les initialiseurs d’objets ne sont en réalité qu’un "confort de syntaxe" pour raccourcir les attributions initiales. Bien, mais pas vraiment très fonctionnel.

Marc

14
marc_s

Un constructeur est une méthode (éventuellement) acceptant des paramètres et renvoyant une nouvelle instance d'une classe. Il peut contenir une logique d'initialisation. Ci-dessous, vous pouvez voir un exemple de constructeur.


public class Foo
{
    private SomeClass s;
    public Foo(string s)
    {
       s = new SomeClass(s);
    }
}

Considérons maintenant l'exemple suivant:


public class Foo
{
    public SomeClass s { get; set; }
    public Foo() {}
}

Vous pouvez obtenir le même résultat que dans le premier exemple en utilisant un initialiseur d'objet, en supposant que vous puissiez accéder à SomeClass, avec le code suivant:


new Foo() { s = new SomeClass(someString) }

Comme vous pouvez le constater, un initialiseur d’objet vous permet de spécifier des valeurs pour les champs publics et les propriétés publiques (paramétrables) en même temps que la construction est effectuée, ce qui est particulièrement utile lorsque le constructeur ne fournit aucune surcharge lors de l’initialisation de certains champs. Veuillez noter cependant que les initialiseurs d’objet ne sont que du sucre syntaxique et qu’après la compilation, ils ne seront pas vraiment différents d’une séquence d’assignations.

4
em70