web-dev-qa-db-fra.com

Constructeur vs priorité d'initialisation d'objet en C #

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;
}
51
bbill

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.

44
Paul Sasik

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 .

enter image description here

35
Tamim Al Manaseer

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;
16
juharr
b = new A(true) {foo = false};

est effectivement court pour:

A temp = new A(true);
temp.foo = false;
A b = temp;

temp est une variable autrement inaccessible. Le constructeur est toujours exécuté en premier, suivi des propriétés initialisées.

11
Lee

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.
4
Chris