C # appelle un constructeur du corps d’un autre

J’ai besoin d’appeler un constructeur du corps d’un autre, comment faire ça?

Fondamentalement

class foo { public foo (int x, int y) { } public foo (ssortingng s) { // ... do something // call another constructor this (x, y); // doesn't work foo (x, y); // neither } } 

Vous ne pouvez pas

Vous devrez trouver un moyen de chaîner les constructeurs, comme dans:

 public foo (int x, int y) { } public foo (ssortingng s) : this(XFromSsortingng(s), YFromSsortingng(s)) { ... } 

ou déplacez votre code de construction dans une méthode de configuration commune, comme ceci:

 public foo (int x, int y) { Setup(x, y); } public foo (ssortingng s) { // do stuff int x = XFromSsortingng(s); int y = YFromSsortingng(s); Setup(x, y); } public void Setup(int x, int y) { ... } 

this(x, y) est correct, mais il doit être avant le début du corps du constructeur:

 public Foo(int x, int y) { ... } public Foo(ssortingng s) : this(5, 10) { } 

Notez que:

  • Vous ne pouvez enchaîner que sur un constructeur, que this soit this base ou ce constructeur – ce constructeur peut bien sûr en enchaîner un autre.
  • Vous ne pouvez pas enchaîner avec un constructeur après avoir exécuté du code dans le corps du constructeur.
  • Vous ne pouvez pas utiliser this dans les arguments de l’autre constructeur, y compris les méthodes d’instance d’appel – mais vous pouvez appeler des méthodes statiques.
  • Tous les initialiseurs de variables d’instance sont exécutés avant l’appel chaîné.

J’ai un peu plus d’informations dans mon article sur le chaînage des constructeurs .

Pour appeler à la fois le constructeur de base et celui de cette classe, vous devez explicitement utiliser la syntaxe ci-dessous (notez qu’en C # vous ne pouvez pas l’utiliser pour initialiser des champs comme en C ++):

 class foo { public foo (int x, int y) { } public foo (ssortingng s) : this(5, 6) { // ... do something } } 

// EDIT: remarqué, que vous avez utilisé x, y dans votre échantillon. Bien sûr, les valeurs données lors de l’appel de ctor de cette manière ne peuvent pas s’appuyer sur les parameters d’un autre constructeur, elles doivent être résolues autrement (elles n’ont pas besoin d’être constantes comme dans l’exemple de code édité ci-dessus). Si x et y sont calculés à partir de s , vous pouvez le faire de cette façon:

 foo public (ssortingng s): this (GetX (s), GetY (s))

Ceci n’est pas pris en charge – voir http://www.yoda.arachsys.com/csharp/constructors.html .

Ce que vous pouvez faire cependant, c’est implémenter une méthode commune (privée) que vous appelez des différents constructeurs …

Je me suis heurté à ce problème une ou deux fois. Ce que j’ai dû faire était d’extraire la logique nécessaire dans cet autre constructeur dans une méthode de private void et de l’appeler aux deux endroits.

 class foo { private void Initialize(int x, int y) { //... do stuff } public foo(int x, int y) { Initialize(x, y); } public foo(ssortingng s_ { // ... do stuff Initialize(x, y) // ... more stuff } }