2010-09-03 8 views
8

He usado muchas propiedades de auto pero me he alejado cada vez más de esa configuración de clases con campos de respaldo de solo lectura inicializados en el constructor. Elimino todos los colocador y solo agrego el respaldo si la propiedad claramente necesita un colocador.C# constructores vs auto-propiedades e inicializadores de objetos

Me parece que esto hace que mis clases sean más robustas y elegantes en cuanto a OO y me estoy pateando por no haber hecho esto antes.

Creo que los constructores están muy poco utilizados generalmente en ejemplos de código C# y creo que las auto-propiedades y el inicializador de objetos son una gran parte de esto, así que mi pregunta es ¿por qué el equipo C# empuja características como esta y no se centra más en ofrece funciones que impulsan más las mejores prácticas. En general creo que es muy fácil escribir código incorrecto y creo que se puede hacer más para ayudar a los programadores a escribir un buen código

+0

No todos los tipos deben ser inmutables. Es perfectamente común (y saludable) tomar un tipo mutable en un constructor, luego copiarlo a un miembro privado. Luego está protegido contra cambios a través de un código externo (suponiendo que haga lo mismo para cualquier dependencia mutable). Esto es especialmente cierto para objetos de datos antiguos. –

Respuesta

13

Por las conversaciones, creo que el equipo C# entiende que han hecho más fácil escribir tipos mutables sin proporcionar un beneficio similar para tipos inmutables. No es que hayan endurecido la inmutabilidad con el tiempo, simplemente no lo han hecho más fácil ... excepto por los tipos anónimos, que son inmutables, pero tienen otros inconvenientes. Desde luego, no me gustaría que se quiten las propiedades automáticas, donde son apropiadas, son realmente útiles. Me encantaría tener el equivalente para las propiedades de solo lectura (lo que les permite establecerse solo en el constructor).

He encontrado que los argumentos nombrados de C# 4 y los parámetros opcionales han hecho que sea más fácil construir instancias de tipo inmutables: aún puede obtener muchos de los beneficios de los inicializadores de objetos, sin los inconvenientes de mutabilidad. Simplemente proporcione los valores predeterminados para los aspectos de su tipo que sean realmente opcionales, deje el resto como parámetros de constructor obligatorios y la persona que llama puede hacer lo que quiera, utilizando argumentos con nombre para agregar claridad.

Los inicializadores de recopilación son una tuerca más difícil de descifrar, desafortunadamente. Me gustaría ver "encadenados" inicializadores que podría trabajar con colecciones inmutables, de modo que en lugar de llamar repetidamente Add en la misma instancia, el compilador podría crear las llamadas a Plus las cuales sumadas juntas:

ImmutableList<string> x = new ImmutableList<string> { "a", "b", "c" }; 

irían a :

ImmutableList<string> x = new ImmutableList<string>().Plus("a") 
                .Plus("b") 
                .Plus"(c"); 

por supuesto, sería bueno tener colecciones más inmutables en el marco de comenzar con :)

Nada de esto ayuda en el lado auto-props, por supuesto. Tengo que admitir que he estado engañando una cierta cantidad recientemente, fingiendo inmutabilidad utilizando emisores privados:

public string Name { get; private set; } 

Me hace sentir sucia, sin embargo, no por lo que es verdaderamente inmutable cuando esa es mi intención real.

Básicamente, estoy diciendo que siento tu dolor, y estoy bastante seguro de que el equipo de C# lo hace. Sin embargo, tenga en cuenta que tienen recursos limitados, y diseñar un lenguaje es muy difícil.

Puede que encuentre interesante el videos from NDC 2010 - hay una gran mesa redonda con Eric Lippert, Mads Torgersen, Neal Gafter (y yo), y mis propuestas para C# 5 están en otro video.

+0

Sin duda estaría bien si la inmutabilidad fuera más fácil. Para garantizar la inmutabilidad total, debe tener el control total de todas las clases que contiene. Por ejemplo, dijo que los tipos anónimos son inmutables, sin embargo, agregué una matriz y una lista mutable a ella, y pude modificar ambos. Si tiene un miembro accesible públicamente que sea inmutable hoy, se puede hacer mutable mañana, y su inmutabilidad se rompe como resultado. –

+0

Thx, voy a echar un vistazo a esos videos. Después de leer un poco más, parece que F # está tratando con estas cosas de una manera más agradable, bloqueando objetos por defecto y permitiendo mutabilidad si es necesario. Supongo que el legado detiene al equipo C# yendo en esa dirección. ¿Cuáles son sus pensamientos sobre F # vs C# Jon? – terjetyl

+0

@TT: No he tenido tanta experiencia como me gustaría en F #, pero sí me gustan varias cosas que F # hace, sin duda. Muchas de las sugerencias que hice sobre C# 5 se basaron en F #. –

0

me parece constructores están muy infrautilizados en general en C# ejemplos de código y creo auto-propiedades y inicializador de objeto son una gran parte de esta

Si el objeto tiene una gran cantidad de propiedades, que claramente Don No quiero inicializarlos todos desde el constructor. Tener que aprobar más de, digamos, 4 o 5 parámetros es bastante malo para la legibilidad (a pesar de que Intellisense hace que sea más fácil escribir). Además, si solo desea inicializar algunas propiedades y usar el valor predeterminado para otras propiedades, o necesita muchas sobrecargas de constructor, o tiene que pasar estos valores predeterminados explícitamente al constructor.

En tales casos los inicializadores de objeto son muy útiles, siempre y cuando las propiedades no son de sólo lectura (pero como Jon señaló, parámetros opcionales en C# 4 son una buena alternativa)

¿Por qué el C# equipo push características como esta y no se está enfocando más en entregar características empujando mejores prácticas más

Creo que los inicializadores de objetos se introdujeron porque eran necesarios para Linq: no se podían crear tipos anónimos sin ellos. En cuanto a las propiedades automotrices, son menos vitales, pero probablemente fue fácil de implementar y puede ahorrar mucho tiempo para las propiedades que no hacen más que encapsular un campo.

1

Elimino todos los colocadores y solo agrego el respaldo si la propiedad claramente necesita un colocador. Me parece que esto hace que mis clases sean más robustas y elegantes OO sabio

Estoy totalmente de acuerdo con usted. Me enfrenté al código heredado donde hay muchos inicializadores de objetos usados ​​para alguna jerarquía de clases. Necesitaba agregar algunas propiedades y luego tuve un dolor de cabeza al encontrar todos los lugares donde se construyen instancias de clase. Primera vez que me presenté. Y ahora necesito agregar una propiedad más. ¡Esto es Loco!

Para restringir el uso de los inicializadores de objetos, eliminé el constructor sin parámetros.

Cuestiones relacionadas