2010-10-03 20 views
5

tengo unas pocas cosas:¿Por qué molestarse con los inicializadores? (.net)

AudioPlayer player = new AudioPlayer(); 
player.Directory = vc.Directory; 
player.StartTime = vc.StarTime; 
player.EndTime = vc.EndTime; 

Pero podría tener esto:

AudioPlayer player = new AudioPlayer 
{ 
    Directory = vc.Directory, 
    StartTime = vc.StarTime, 
    EndTime = vc.EndTime 
}; 

Si convierto en 'nueva forma de escribir las cosas', ¿Qué gano además ilegibilidad? ¿Me acercará más a las funciones lambda (=>)?

¿Tiene algo que ver con RAII?

ADEMÁS:

Algunos respondieron que la inicialización normal podría dejó el objeto en estado no válido "después de establecer ejemplo únicamente una propiedad Directorio - mi observación es que es alguien que estaba diseñando el objeto probablemente lo diseñó en una forma en que solo los valores que DEBEN introducirse realmente se ingresan a través del constructor real, y todos los demás se pueden modificar posteriormente libremente.

+0

Bueno, parece que mi corazonada sobre lambdas era correcta. –

+0

Revisa tu libro de idiomas favorito de C# para "tipos anónimos". –

+0

@Hans: como en 'ad-hoc-property-containers'? –

Respuesta

2

Considere que desea pasar su objeto recién creado a algún método (y no hacer nada más con él). o bien se puede escribir de la manera antigua:

AudioPlayer player = new AudioPlayer(); 
player.Directory = vc.Directory; 
player.StartTime = vc.StarTime; 
player.EndTime = vc.EndTime; 
some.Method(player); 

O puede utilizar inicializadores de objeto:

some.Method(
    new AudioPlayer 
    { 
     Directory = vc.Directory, 
     StartTime = vc.StarTime, 
     EndTime = vc.EndTime 
    }); 

Usando initilizers objeto, puede ver claramente lo que hace el código y que el objeto no se utiliza más adelante .

Además, creo que la legibilidad (y "capacidad de escritura") es mejor: no tiene que repetir el nombre de la variable sin fin.

+0

Bueno, aquí viene la palabra clave 'con' de VB6! :) –

1

Creo que se ha agregado esta sintaxis porque es más fácil de usar con la expresión lambda, por lo que puede hacer algo como item => new Person() { Name = item.Name } fácilmente.

no creo que tenga nada que ver con RAII aunque ..

10

Con un ejemplo tan simple, que de hecho no gana mucho. Sin embargo, se vuelve diferente cuando tiene esto:

var player = new AudioPlayer 
{ 
    Car = new Car() 
    { 
     WheelSize = new Inch(21), 
     Driver = new Person() 
     { 
      Age = 53, 
      Type = LicenseType.B, 
      Family = 
      { 
       new Person("Jane"), 
       new Person("Pieter"), 
       new Person("Anny") 
      } 
     } 
    } 
    Directory = vc.Directory, 
    StartTime = vc.StarTime, 
    EndTime = vc.EndTime 
}; 

Intente hacer esto de la manera antigua. Se pone realmente feo.

+0

+1. Un punto trivial, pero las parantheses no son necesarias cuando se llama al constructor sin parámetros. – Ani

+0

@Ani: Es por eso que 'nuevo AudioPlayer' no tiene parantheses :-) – Steven

1

Obtiene 21 caracteres menos de código. Y menos código significa menos errores. Y para obtener aún más puede usar la inferencia implícita del tipo de variable: var player = new AudioPlayer {

2

No solo obtiene la ilegibilidad, sino que también gana una mayor capacidad de causar errores al poner los objetos en un estado no válido.

Lo único que tiene que ver con RAII es que RAII depende de invariantes sensibles, y los inicializadores hacen que sea más fácil romper invariantes.

Sin embargo, puede ser muy útil para crear un valor anónimo, o en la creación de objetos de estilo simple de datos antiguos (donde la clase es un contenedor "tonto" de valores y las invariantes no son tan importantes). Estos pueden ser particularmente útiles con las funciones lambda y las expresiones linq, aunque no son absolutamente necesarias ni están restringidas a ellas.

Cuando una clase mantiene una invariante, no es una buena idea inicializarla de tal manera, y como regla, cualquier reescritura de un constructor que toma valores a la nueva sintaxis es una mala idea.

En su ejemplo, su primer caso no utiliza su constructor para inicializar a un estado válido garantizado. Es un mal olor (¿qué debe hacer un jugador antes de tener un directorio, hora de inicio y hora de finalización?), Pero cuando es razonable para una clase determinada, también lo es el uso de la nueva sintaxis.

Que la nueva sintaxis puede configurar el objeto en una sola expresión, que a su vez puede ser parte de otra expresión, es donde esto podría ser útil, y eso sí que se incluye en las expresiones lambda.

2

Los inicializadores son necesarios, y no solo útiles, cuando se trata de tipos anónimos.

ej .:

var x = new Foo {= "foo", Bar = "bar"};

+0

Esta instancia particular, ¿es compatible con .net 2.0? Es decir. ¿es una característica de un IDE, compilador o tiempo de ejecución .net? –

Cuestiones relacionadas