creando parámetros de objeto en {}?

14

Estoy tratando de decodificar un fragmento de código de un libro:

List<Person> people = new List<Person>()
{
new Person {FirstName="Homer",LastName="Simpson",Age=47},
new Person {FirstName="Marge",LastName="Simpson",Age=45}
};

Person es solo una clase simple que hicieron, con un montón de campos: Nombre, Apellido, etc.

Lo que no entiendo es, ¿no enviamos parámetros a un constructor de Persona entre paréntesis no rizados? Traté de replicar este código, pero no parece volar, ¿algún tomador?

Gracias por tu aporte.

Realidad Disfunción
fuente
1
"Intenté replicar este código, pero parece que no vuela" <- necesita usar C # 3 (VS 2008) o posterior para que esta sintaxis esté disponible.
AakashM
Tenga en cuenta las diferencias entre los dos conceptos: inicialización de objetos y población de objetos. En general, haces la inicialización en el constructor. El método de su ejemplo se utiliza mejor para la población, no para la inicialización.
NoChance

Respuestas:

27

C # le permite especificar parámetros de propiedad en llaves cuando se inicializa el objeto. Esto le permite elegir qué elementos inicializar y cuáles dejar como predeterminados.

Un constructor, por otro lado, ejecuta un solo bloque de código con un conjunto fijo de parámetros. Por lo tanto, para obtener el mismo efecto, tendría que crear múltiples constructores, todos con las diversas combinaciones de propiedades que desee inicializar, lo que podría ser tedioso.

var x = new Person {FirstName="Homer",LastName="Simpson",Age=47}; 

es exactamente equivalente a esto:

var x = new Person();
x.FirstName="Homer";
x.LastName="Simpson";
x.Age=47;

Excepto que es más corto y posiblemente más fácil para la vista.

También permite construcciones como las que demostró en su pregunta, lo que sería muy tedioso si tuviera que crear variables temporales e inicializarlas como lo hice aquí antes de agregarlas a la lista. (Que es como solía hacerlo). Todo sin requerir un constructor definido explícitamente que tome la lista de parámetros deseada, que puede o no estar disponible.

Además, tenga en cuenta que si bien un constructor puede inicializar propiedades con un setter privado, esta técnica (como debería ser obvio del ejemplo proporcionado) solo funcionará si tiene un setter público para la propiedad. También tenga en cuenta que mi ejemplo abreviado implícitamente llamó al constructor predeterminado (sin parámetros), que por lo tanto tendría que estar presente.

tylerl
fuente
Puede valer la pena agregar que debido a esto, las propiedades inicializadas en las llaves deben ser públicamente configurables.
Yam Marcovic
@YamMarcovic ah. si. Nota agregada a ese efecto.
tylerl
2
Ah, estoy iluminado, excelente explicación.
RealityDysfunction
2
Para obtener un efecto muy similar con un solo constructor, puede hacer que todos sus parámetros sean opcionales. Entonces podría hacer algo como new Person(lastName: "Simpson"), omitiendo los parámetros firstNamey age.
svick
Esto no var x = new Person("Homer", "Simpson", 47);
explica