int a, b, c;
Constructor()
{
a = 5;
b = 10;
c = 15;
//do stuff
}
Constructor(int x, int y)
{
a = x;
b = y;
c = 15;
//do stuff
}
Constructor(int x, int y, int z)
{
a = x;
b = y;
c = z;
//do stuff
}
Pour éviter la duplication de "trucs" et quelques affectations, j'ai essayé quelque chose comme:
int a, b, c;
Constructor(): this(5, 10, 15)
{
}
Constructor(int x, int y): this(x, y, 15)
{
}
Constructor(int x, int y, int z)
{
a = x;
b = y;
c = z;
//do stuff
}
Cela fonctionne pour ce que je veux faire, mais parfois je dois utiliser un long code pour créer de nouveaux objets ou faire des calculs:
int a, b, c;
Constructor(): this(new Something(new AnotherThing(param1, param2, param3),
10, 15).CollectionOfStuff.Count, new SomethingElse("some string", "another
string").GetValue(), (int)Math.Floor(533 / 39.384))
{
}
Constructor(int x, int y): this(x, y, (int)Math.Floor(533 / 39.384))
{
}
Constructor(int x, int y, int z)
{
a = x;
b = y;
c = z;
//do stuff
}
Ce code est à peu près le même qu'avant, seuls les paramètres transmis ne sont pas très lisibles. Je préférerais faire quelque chose comme:
int a, b, c;
Constructor(): this(x, y, z) //compile error, variables do not exist in context
{
AnotherThing at = new AnotherThing(param1, param2, param3);
Something st = new Something(aThing, 10, 15)
SomethingElse ste = new SomethingElse("some string", "another string");
int x = thing.CollectionOfStuff.Count;
int y = ste.GetValue();
int z = (int)Math.Floor(533 / 39.384);
//In Java, I think you can call this(x, y, z) at this point.
this(x, y, z); //compile error, method name expected
}
Constructor(int x, int y): this(x, y, z) //compile error
{
int z = (int)Math.Floor(533 / 39.384);
}
Constructor(int x, int y, int z)
{
a = x;
b = y;
c = z;
//do stuff
}
Fondamentalement, je construis les paramètres dans le corps du constructeur. Ensuite, j'essaie de passer ces paramètres construits à un autre constructeur. Je pense que je me souviens avoir pu utiliser les mots-clés "this" et "super" pour appeler des constructeurs à l'intérieur du corps d'un autre constructeur lors du codage en Java. Cela ne semble pas possible en C #.
Existe-t-il un moyen de le faire facilement? Ai-je fait quelque chose de mal? Si ce n'est pas possible, devrais-je simplement m'en tenir au code illisible?
Je suppose que je pourrais toujours couper le code dupliqué dans une autre méthode complètement en dehors des constructeurs. Ensuite, chaque constructeur ferait sa propre chose et appellerait le code partagé par les autres constructeurs.
Au lieu d'appeler une méthode d'initialisation à partir de tous les constructeurs (ce qui vous empêche d'utiliser les champs readonly
) ou des méthodes d'usine (qui introduisent une complexité supplémentaire lorsque vous avez des classes dérivées), vous pouvez utiliser un objet paramètre :
int a, b, c;
public Constructor()
: this(new ConstructorParameters())
{
}
public Constructor(int x, int y)
: this(new ConstructorParameters(x, y))
{
}
public Constructor(int x, int y, int z)
{
a = x;
b = y;
c = z;
//do stuff
}
private Constructor(ConstructorParameters parameters)
: this(parameters.X, parameters.Y, parameters.Z)
{
}
private class ConstructorParameters
{
public int X;
public int Y;
public int Z;
public ConstructorParameters()
{
AnotherThing at = new AnotherThing(param1, param2, param3);
Something st = new Something(at, 10, 15)
SomethingElse ste = new SomethingElse("some string", "another string");
X = st.CollectionOfStuff.Count;
Y = ste.GetValue();
Z = (int)Math.Floor(533 / 39.384);
}
public ConstructorParameters(int x, int y)
{
X = x;
Y = y;
Z = (int)Math.Floor(533 / 39.384);
}
}
Tu peux faire
Constructor() : this(5, 10, 15)
{
}
Constructor(int x, int y) : this(x, y, 15)
{
}
Constructor(int x, int y, int z)
{
int a = x;
int b = y;
int c = z;
//do stuff
}
Cependant, si vous avez besoin de faire une logique sophistiquée en fonction des paramètres, j'utiliserais un modèle d'usine :
public class myclass
{
private myclass(int x, int y, int z)
{
int a = x;
int b = y;
int c = z;
//do stuff
}
public static myclass Create()
{
AnotherThing at = new AnotherThing(param1, param2, param3);
Something st = new Something(aThing, 10, 15)
SomethingElse ste = new SomethingElse("some string", "another string");
int x = thing.CollectionOfStuff.Count;
int y = ste.GetValue();
int z = (int)Math.Floor(533 / 39.384);
return new myclass(x, y ,z);
}
public static myclass Create(int x, int y)
{
if (x = 1)
return new myclass(x, y, 2)
else
return new myclass(x, y, 15);
}
public static myclass Create(int x, int y, int z)
{
//so on and so forth
return new myclass(x, y, z);
}
}
Bien que vous n'ayez pas besoin d'un modèle d'usine, cela rend définitivement la logique de votre constructeur lisible.