J'ai appris l'initialiseur d'objets en C # récemment, mais maintenant je me demande comment cela fonctionne quand il entre en conflit avec le constructeur.
public class A
{
public bool foo { get; set; }
public A()
{
foo = true;
}
public A(bool bar)
{
foo = bar;
}
}
Que se passe-t-il lorsque j'essaie ceci?
public class B
{
a = A() {foo = false};
b = A(true) {foo = false};
}
Une valeur par défaut dans le constructeur est-elle un bon moyen d'avoir un bool
qui commence vrai et peut être modifié?
public A(bar=true)
{
foo = bar;
}
De la documentation :
Le compilateur traite les initialiseurs d'objet en accédant d'abord au constructeur d'instance par défaut, puis en traitant les initialisations de membre.
Cela signifie que dans le cas le plus simple (initialisation d'objet nommé), il s'agit essentiellement d'un raccourci (ou sucre syntaxique) pour appeler le constructeur par défaut, puis pour appeler le ou les régleurs de propriétés. Dans le cas des types anonymes, ce type d'initialisation est en fait requis et pas seulement du sucre.
Pour la 2ème partie de votre question: c'est plus une question de style mais si vous avez une propriété cruciale je ne créerais pas de constructeur avec une valeur par défaut. Faites en sorte que le code client définisse explicitement la valeur. Je ne sais pas non plus pourquoi faire quelque chose comme ça: b = A(true) {foo = false};
serait une bonne idée à moins que vous ne participiez à un concours d'obscurcissement de code.
Un peu de prudence cependant:
... si le constructeur par défaut est déclaré privé dans la classe, les initialiseurs d'objets qui nécessitent un accès public échoueront.
Les initialiseurs d'objets ne sont que du sucre syntaxique, dans votre IL assemblé compilé, ils se traduisent en instructions distinctes, vérifiez-le ILSpy .
Le constructeur apparaît d'abord, puis l'initialiseur d'objet. N'oubliez pas que
a = new A() { foo = false };
est identique à
var temp = new A();
temp.foo = false;
a = temp;
b = new A(true) {foo = false};
est effectivement court pour:
A temp = new A(true);
temp.foo = false;
A b = temp;
où temp
est une variable autrement inaccessible. Le constructeur est toujours exécuté en premier, suivi des propriétés initialisées.
Essentiellement ce que Paul a déjà lié:
De la spécification du langage C # 5 (7.6.10.1)
Processing of an object creation expression that includes an object initializer or
collection initializer consists of first processing the instance constructor and then
processing the member or element initializations specified by the object initializer or
collection initializer.