remarks net method generate example description cref c# design

net - remarks c#



Los constructores de anidamiento(o los métodos de fábrica) son buenos, o cada uno debe hacer todo el trabajo de inicio (2)

¿Es una buena idea (desde un punto de vista de diseño) anidar las llamadas de los constructores para métodos de estilo New o Factory sobrecargados? Esto es principalmente para constructores simples, donde cada sobrecarga se basa en la anterior.

MyClass( arg1 ) { _arg1 = arg1; _otherField = true; _color="Blue" } MyClass( arg1, arg2) : this(arg1) { _arg2 = arg2 } MyClass( arg1, arg2, arg3) : this(arg1, ar2) { _arg3 = arg3; }

O con los métodos de fábrica:

static NewInstance(arg1 ) { _arg1 = arg1; } static NewInstance(arg1, arg2) { f = NewInstance(arg1); f._arg2 = arg2; } //... and so on

Puedo ver algunos inconvenientes en ambos lados

  • Anidar esconde lo que el constructor está haciendo
  • No anidar duplica toda la funcionalidad

Entonces, hacer esto es una buena idea, o me prepara para algo que simplemente no veo como un problema. Por alguna razón, me siento incómodo al hacerlo, principalmente porque divide la responsabilidad de inicializar.

Editar: @Jon Skeet : ahora veo por qué esto me molestaba tanto. ¡Lo estaba haciendo al revés! Lo escribí todo y ni siquiera lo noté, solo olía. En la mayoría de los otros casos que tengo (que escribí), hazlo de la manera que recomiendas, pero ciertamente este no es el único que he hecho así. Me doy cuenta de que los más complicados lo hice correctamente, pero los simples parecen haber sido descuidados. Me encantan las microediciones. ¡También me gustan los acrónimos!


Creo que es razonable encadenar a los constructores, pero lo hago de otra forma: la versión con menos parámetros llama a la versión con más parámetros. De esta forma deja muy claro lo que está sucediendo, y toda la "lógica" real (más allá de los valores por defecto) está en un solo lugar. Por ejemplo:

public Foo(int x, int y) { this.x = x; this.y = y; precomputedValue = x * y; } private static int DefaultY { get { return DateTime.Now.Minute; } } public Foo(int x) : this(x, DefaultY) { } public Foo() : this(1, DefaultY) { }

Tenga en cuenta que si tiene muchas sobrecargas de constructor, puede preferir pasar a métodos de fábrica estáticos, lo que generalmente hace que el código sea más claro, y permite que múltiples métodos tomen el mismo conjunto de parámetros, por ejemplo

public static XmlDocument FromText(string xml) public static XmlDocument FromFile(string filename)


Edición de 2016 : Todavía por delante, C # está reduciendo radicalmente o eliminando su soporte de registros y soporte de constructor predeterminado para C # 7, quizás C # 8 finalmente .

2015 Edit : estaba muy adelantado a la hora. C # 6 y C # 7 están eliminando la necesidad de constructores.

Si está desarrollando en .Net 3.5, le recomiendo que nunca use constructores. La única excepción que le dejo es si está usando un constructor de inyección para la inyección de dependencia. Con .Net 3.5 crearon los inicializadores de objetos que le permiten hacer

var myclass = New MyClass { arg1 = "lala", arg2 ="foo" }

Esto iniciará la clase con los valores asignados para arg1 y arg2 mientras deja arg3 como

default(typeof(arg3)).