¿Cuál es la diferencia entre un inicializador de objetos y un constructor?

¿Cuáles son las diferencias entre los dos y cuándo usarías un “inicializador de objetos” sobre un “constructor” y viceversa? Estoy trabajando con C #, si eso es importante. Además, ¿el método de inicialización de objetos es específico para C # o .NET?

Los Iniciales de objetos fueron algo agregado a C # 3, para simplificar la construcción de objetos cuando estás usando un objeto.

Los constructores se ejecutan, con 0 o más parámetros, y se utilizan para crear e inicializar un objeto antes de que el método de llamada obtenga el control del objeto creado. Por ejemplo:

MyObject myObjectInstance = new MyObject(param1, param2); 

En este caso, el constructor de MyObject se ejecutará con los valores param1 y param2 . Ambos se usan para crear el nuevo MyObject en la memoria. El objeto creado (que se configura con esos parámetros) se devuelve y se establece en myObjectInstance .

En general, se considera una buena práctica que un constructor requiera los parámetros necesarios para configurar completamente un objeto, de modo que sea imposible crear un objeto en un estado no válido.

Sin embargo, a menudo hay propiedades “adicionales” que se pueden establecer, pero no son necesarias. Esto podría ser manejado a través de constructores sobrecargados, pero conduce a tener muchos constructores que no son necesariamente útiles en la mayoría de las circunstancias.

Esto lleva a los inicializadores de objetos: un inicializador de objetos le permite establecer propiedades o campos en su objeto una vez que ha sido construido, pero antes de que pueda usarlo de otra forma. Por ejemplo:

 MyObject myObjectInstance = new MyObject(param1, param2) { MyProperty = someUsefulValue }; 

Esto se comportará de la misma manera que si haces esto:

 MyObject myObjectInstance = new MyObject(param1, param2); myObjectInstance.MyProperty = someUsefulValue; 

Sin embargo, en entornos de subprocesos múltiples, la atomicidad del inicializador de objetos puede ser beneficiosa, ya que impide que el objeto se encuentre en un estado no inicializado por completo (consulte esta respuesta para obtener más detalles): es nulo o se inicializó como usted pretendía.

Además, los inicializadores de objetos son más fáciles de leer (especialmente cuando se configuran varios valores), por lo que le dan el mismo beneficio que muchas sobrecargas en el constructor, sin la necesidad de tener muchas sobrecargas que compliquen la API para esa clase.

Un constructor es un método definido en un tipo que toma un número específico de parámetros y se usa para crear e inicializar un objeto.

Un inicializador de objetos es un código que se ejecuta en un objeto después de un constructor y se puede usar para establecer de manera sucinta cualquier cantidad de campos en el objeto a los valores especificados. La configuración de estos campos ocurre después de que se llama al constructor.

Utilizaría un constructor sin la ayuda de un inicializador de objetos si el constructor establecía suficientemente el estado inicial del objeto. Sin embargo, un inicializador de objetos debe usarse junto con un constructor. La syntax requiere el uso explícito o implícito (VB.Net y C #) de un constructor para crear el objeto inicial. Utilizaría un inicializador de objetos cuando el constructor no inicializara suficientemente el objeto para su uso y algunos conjuntos sencillos de campo y / o propiedad lo harían.

Cuando tu lo hagas

 Person p = new Person { Name = "a", Age = 23 }; 

esto es lo que hace esencialmente un inicializador de objetos:

 Person tmp = new Person(); //creates temp object calling default constructor tmp.Name = "a"; tmp.Age = 23; p = tmp; 

Ahora esto facilita un comportamiento como este . Saber cómo funcionan los inicializadores de objetos es importante.

Si tiene propiedades que DEBEN establecerse en su objeto para que funcione correctamente, una forma es exponer un solo constructor que requiera esas propiedades obligatorias como parámetros.

En ese caso, no puede crear su objeto sin especificar esas propiedades obligatorias. Algo como eso no puede ser impuesto por los inicializadores de objetos.

Los inicializadores de objetos son solo una “conveniencia de syntax” para acortar las asignaciones iniciales. Agradable, pero no muy funcionalmente relevante.

Bagazo

Un constructor es un método (posiblemente) que acepta parámetros y devuelve una nueva instancia de una clase. Puede contener lógica de inicialización. A continuación puede ver un ejemplo de un constructor.

 public class Foo { private SomeClass s; public Foo(string s) { s = new SomeClass(s); } } 

Ahora considere el siguiente ejemplo:

 public class Foo { public SomeClass s { get; set; } public Foo() {} } 

Puede obtener el mismo resultado que en el primer ejemplo utilizando un inicializador de objetos, suponiendo que puede acceder a SomeClass, con el siguiente código:

 new Foo() { s = new SomeClass(someString) } 

Como puede ver, un inicializador de objetos le permite especificar valores para campos públicos y propiedades públicas (configurables) al mismo tiempo que se realiza la construcción, y eso es especialmente útil cuando el constructor no proporciona ninguna sobrecarga inicializando ciertos campos. Sin embargo, tenga en cuenta que los inicializadores de objetos son solo azúcar sintáctico y que después de la comstackción no diferirán realmente de una secuencia de tareas.