20 de noviembre de 2009

C#, Inicializadores de Objeto y de Colección

Los inicializadores de objeto permiten asignar valores a los campos o propiedades de un objeto en el momento de la creación sin tener que invocar explícitamente un constructor.

C# 3.0, Nueva Característica

Esta característica fue incorporada a partir de la versión C# 3.0 y sigue el camino de la simplificación de código, al igual que otras características que iré comentando en sucesivos artículos. Pero en fin, veamos un ejemplo que nos deje el concepto del todo claro:

namespace Pruebas
{
    class Program
    {
        static void Main(string[] args)
        {
            // Inicializador de Objeto
            Contacto objContacto =
                new Contacto { IdContacto=3, Nombre="Pedro", Telefono = "601 01 01 01" };
           
            //Inicializador de Colección
            List<Contacto> lstContactos = new List<Contacto>
            {
                new Contacto { IdContacto=1, Nombre="Pedro", Telefono="601 01 01 01" },
                new Contacto { IdContacto=2, Nombre="Maria", Telefono="601 01 01 02" },
                objContacto,
                new Contacto { IdContacto=4, Nombre="Juana", Telefono="601 01 01 03" }
            };
            //Inicializador de Array – Variante 1
            var arrContactos1 = new[]
            {
                new Contacto { IdContacto=11, Nombre="Pedro", Telefono="601 01 01 01" },
                new Contacto { IdContacto=12, Nombre="Maria", Telefono="601 01 01 02" },
                new Contacto { IdContacto=13, Nombre="Juana", Telefono="601 01 01 03" }
            };
            //Inicializador de Array – Variante 2
            Contacto[] arrContactos2 =
            {
                new Contacto { IdContacto=14, Nombre="Pedro", Telefono="601 01 01 01" },
                new Contacto { IdContacto=15, Nombre="Maria", Telefono="601 01 01 02" },
                new Contacto { IdContacto=16, Nombre="Juana", Telefono="601 01 01 03" }
            };
 
        }
    }
 
    public class Contacto
    {
        public int IdContacto {get; set;}
        public string Nombre { get; set; }
        public string Telefono { get; set; }
    }
}

Y así de simple es crearnos un objeto o una colección de objetos e inicializarlos en la misma línea.

Nota: En el ejemplo, hemos usado la clase Contacto y en ella hemos usado otra nueva característica de C# 3.0, se trata de las propiedades auto implementadas. Para obtener más información, consulte Propiedades auto implementadas.

 

Inicializador de Objeto Avanzado

El ejemplo anterior es bastante útil y frecuente, pero en determinadas ocasiones pudiéramos encontrarnos con la necesidad de inicializar objetos que poseen propiedades de solo lectura, que solo son seteados a través de constructores, veamos el ejemplo:

namespace Pruebas
{
   class Program
   {
     static void Main(string[] args)
     {
       Contacto objContacto = new Contacto { Nombre="Pedro", Telefono = "601010101" };
           
       var ctoEspecial1 =
              new ContactoEspecial(1) { Nombre="Mario", Telefono="622010101" };
 
       ContactoEspecial ctoEspecial2 =
              new ContactoEspecial(1) { Nombre="Paloma", Telefono="622010102" };
     }
   }
   public class Contacto
   {
        public string Nombre { get; set; }
        public string Telefono { get; set; }
   }
   public class ContactoEspecial : Contacto
   {
        public int TipoContacto { get; private set; }
        public ContactoEspecial(int tipo)
        {
            TipoContacto = tipo;
        }
   }
}

En el código anterior, hemos creado 2 clases “Contacto” y “ContactoEspecial”, esta ultima hereda de la clase contrato y adiciona una nueva propiedad “TipoContacto” que podemos leer pero no escribir, es de solo lectura (fíjate en el modificador “private”).

Al ser “TipoContacto” de solo lectura, no podemos inicializar esta propiedad de forma directa como hicimos en el primer ejemplo de código, para ello fue necesario llamar al constructor de la clase y luego continuar la inicialización:

var ctoEspecial1 =  new ContactoEspecial(1) { Nombre="Mario", Telefono="622010101" };
ContactoEspecial ctoEspecial2 = new ContactoEspecial(1) { Nombre="Paloma", Telefono="622010102" };
 
Estas dos líneas anteriores son muy similares en cuanto al resultado obtenido, ambas inicializan un objeto de tipo ContactoEspecial, solo la he empleado para poner un ejemplo de inferencia de tipo, de esto hablaré mas en otro momento.

Artículos Relacionados: