remarks example cref c# parameters constructor this code-duplication

example - params comments c#



¿Cómo puedo usar múltiples constructores para eliminar código duplicado mientras mantengo la legibilidad? (2)

Como alternativa a llamar a un método de inicialización de todos los constructores (que le impide usar campos de readonly ) o métodos de fábrica (que introducen complejidad adicional cuando tiene clases derivadas), puede usar un objeto de parámetro :

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); } }

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 }

Para evitar la duplicación de "cosas" y algunas tareas, probé algo como:

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 }

Esto funciona para lo que quiero hacer, pero a veces necesito usar un código extenso para crear nuevos objetos o hacer algunos cálculos:

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 }

Este código es prácticamente el mismo que antes, solo los parámetros que se pasan no son muy legibles. Prefiero hacer algo como:

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 }

Básicamente estoy construyendo los parámetros dentro del cuerpo constructor. Entonces estoy tratando de pasar esos parámetros construidos a otro constructor. Creo que recuerdo haber podido utilizar las palabras clave "este" y "super" para llamar a los constructores mientras estaba dentro del cuerpo de otro constructor al codificar en Java. No parece posible en C #.

¿Hay alguna manera de hacer esto fácilmente? ¿Hice algo incorrectamente? Si esto no es posible, ¿debería seguir con el código ilegible?

Creo que siempre podría cortar el código duplicado en otro método completamente fuera de los constructores. Entonces cada constructor simplemente haría lo suyo y llamaría al código compartido por los otros constructores.


Tu puedes hacer

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 }

Sin embargo, si necesita hacer una lógica sofisticada según los parámetros, usaría un patrón de fábrica :

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); } }

Aunque no necesita un patrón de fábrica, definitivamente hace que su lógica de constructor sea legible.