2012-08-28 13 views
8

Escenario muy común: Tengo una clase con múltiples variables de instancia y un constructor que acepta múltiples parámetros. ¿Puedo vincular de alguna manera uno con el otro? Asignar todos los parámetros a las variables de instancia es muy detallado y es una de las situaciones que podría (y debería) estar cubierta por el principio de convención sobre configuración. Mi código de ejemplo es el siguiente:C# Vincular los parámetros del constructor a las variables de instancia

public class myClass 
{  
    private object param1; 
    private object param2; 
    private object param3; 
    private object param4; 

    public myClass(object param1, object param2, object param3, object param4) 
    { 
     this.param1 = param1; 
     this.param2 = param2; 
     this.param3 = param3; 
     this.param4 = param4; 
    } 
} 

¿Existe un fácil manera de deshacerse de esto y sea C# haga su magia de forma automática?

+3

plugins como CodeRush o JustCode puede generar ese código automáticamente para usted. – sloth

+0

También podría ver el uso de fragmentos de código: http://msdn.microsoft.com/en-us/library/ms165392(v=vs.80).aspx Sin embargo, herramientas como las mencionadas por BigYellowCactus le brindarán una mejor productividad . –

+2

Añadir Resharper a la lista anterior. –

Respuesta

2

Aunque hay muchos complementos que pueden hacer este tipo de cosas, vale la pena señalar que si la capacidad nativa de VS2010 + para generar constructores desde un modelo no existe, puede usar un atajo de teclado simple para hacer el trabajo para ti

I.e. si una clase stub:

class MyClass{ 

} 

Y luego, en un método en algún lugar que escribir algo como esto:

object p1, p2, p3; 
//... (get values for p1-3) 
var a = new MyClass(p1, p2, p3); 

Cuando no existe un constructor tal, aparece un botón pequeño ayudante. Si hace clic en eso, o pulsa ALT+SHIFT+F10 (por defecto) se obtiene un menú, una de las opciones sobre los que deban generar un constructor de rutas internas, que a su vez cambiar el código de MyClass de la siguiente manera:

class MyClass 
{ 
    private object p1; 
    private object p2; 
    private object p3; 

    public MyClass(object p1, object p2, object p3) 
    { 
     // TODO: Complete member initialization 
     this.p1 = p1; 
     this.p2 = p2; 
     this.p3 = p3; 
    } 

} 
+2

+1: También puede usar 'ctrl' +' .' para llegar al mismo menú (al menos en VS2010 Express). –

+0

Cool: ¡es mucho más fácil que la versión de tres teclas! –

+0

Eso es genial. Montones de gracias. No es 100% lo que esperaba, pero como Dan señaló, estaba demasiado concentrado en mi situación actual y no consideré muchos aspectos relevantes. Así que supongo Ctrl +. es :) – Jan

5

No hay nada dentro del lenguaje C# que cubra esto, no. Si bien las herramientas pueden generar código para usted, es posible que no necesariamente lo mantengan actualizado y aún así tendrá el código presente y visible. Se podría potencialmente hacer esto en algunos escenarios utilizando la reflexión, por ejemplo:

public MyClass(object param1, object param2, object param3, object param4) 
{ 
    Helpers.PopulateFromConstructor(this, param1, param2, param3, param4); 
} 

... donde había necesidad de especificar los valores en el mismo orden que los parámetros, y mantener los nombres la misma que la campos, etc. También puede encontrar problemas cuando los campos son readonly.

Personalmente, me encantaría: use herramientas para generar el código si lo desea, pero si no, simplemente viva con él.

Tenga en cuenta que es posible que desee realizar la validación a medida que configura los campos, especialmente en lo que respecta a la nulidad. Por lo que su cuerpo del constructor puede realidad terminan así:

public myClass(object param1, object param2, object param3, object param4) 
{ 
    this.param1 = Preconditions.CheckNotNull(param1); 
    this.param2 = param2; 
    this.param3 = Preconditions.CheckNotNull(param3); 
    this.param4 = param4; 
} 

(Para una clase adecuada Preconditions, por supuesto que he mellado gratuitamente la idea de guayaba en código Java, como yo uso que, en día-. a día de codificación. Este es el enfoque que utilizamos en Noda Time también.)

+0

+1 para "chupar" – hmqcnoesy

4

"... podría ser (y debe ser) cubierta por el principio-sobre-configuración de convenciones ..."

"Convención sobre la configuración "normalmente se aplica a una API o marco, como MVC o Entity Framework, no a la idioma en sí. Una API generalmente es enfocada, reutilizable y, sobre todo, , que simplifica la abstracción de la funcionalidad de. En esta situación, dictar convenciones puede ayudar a impulsar la estructura sin comprometer la funcionalidad.

Sin embargo, esto no es cierto para el lenguaje de programación. El lenguaje es amplio y de bajo nivel, y complejo en comparación. Debe restringir a su usuario lo menos posible sin diluir el valor del idioma. Suponer que una "convención" tan amplia sería muy prescriptiva. Más allá de esto, sería peligroso que el compilador suponga que un parámetro con un nombre de pila siempre debe ser asignado a un campo privado de nombre similar.

Por un lado, su convención no es la única comúnmente utilizada. Por ejemplo, un estilo de codificación común sugiere campos privados guiados por subrayado (_param1), que su convención perdería. El constructor puede tener una lógica más allá de esas asignaciones, en cuyo caso su convención es demasiado simple: ¿debería ejecutarse el código "dirigido por la convención" antes o después de cualquier otra lógica de constructor?

Lo más importante, ¿cómo se anularía tal convención? Si, en el constructor, consumiera param1 de alguna otra forma, ¿todavía ejecuta la convención?¿Qué pasa si, en el constructor, asigno un valor diferente a this.param1? ¿Su convención debe ocurrir antes o después del código que el usuario ha agregado?

Incluso estas breves preguntas, para las cuales muchas personas tendrán respuestas muy diferentes e igualmente válidas, son suficientes para sugerir que tal convención no es tan obvia ni fácil de definir, como podría parecer.

+0

Guau, muchos puntos buenos. Creo que lo que estoy buscando es otro capítulo en la lucha de "hacer mi vida más fácil" frente a "mantener mi vida flexible". Creo que la respuesta de Andras es la mejor/más fácil pero más flexible forma de hacerlo. – Jan

+0

¡Y una de las situaciones en las que me gustaría aceptar 2 respuestas! – Jan

Cuestiones relacionadas