martes, 12 de noviembre de 2013

Propiedades Automáticas e Inicializadores de Objetos



Este post que cubre las propiedades automáticas y los inicializadores de objetos, es un post completamente de transición, en el que nos viene a mostrar una forma de realizar acciones que cotidianas, que a partir de la versión 3.0 del Framework, como casi todo lo que se añadió para LinQ, se pueden realizar de una forma más sencilla y escribiendo mucho menos código.


Son ampliamente conocidas, pero me ha parecido interesante dedicarle en post dentro del mundo LinQ, por si había por ahí algún despistadillo que no las conocía.






Recuerda que aquí tienes el indice de todos los posts del Curso de LinQ.





También conocidas como propiedades auto-implementadas, son una nueva opción que nos permite crear una propiedad completa de forma automática y en una sola línea.

Este tipo de creación de propiedades solo se puede realizar cuando tanto el get, como set, no tienen ningún tipo de código extra. Será el compilador el cree el código necesario por nosotros.

public class Persona
{
    public string DNI    { get; set; }
    public string Nombre { get; set; }
    public int    Edad   { get; set; }
}

Visual Studio contiene un Code Snipped para ahorrar todavía más tiempo en su creación y para ello solo tendremos que escribir ‘prop’ y nos añadirá la plantilla de creación:




















También podemos crear propiedades de solo lectura o solo escritura, mediante la palabra reservada private:

public class Persona
{
    public string DNI    { get; private set; } // solo lectura
    public string Nombre { private get; set; } // solo escritura
    public int    Edad   { get; set; }
}


Inicializadores de objetos

La forma tradicional de inicializar un objeto en programación orientada a objetos, es mediante el constructor. Con el fin de escribir menos código y hacer que las clases sean más útiles y accesibles, éstas suelen proporcionar un número limitado de constructores, que representan el grupo de inicializaciones más usado o adecuado. En esto como en todo, nunca llueve a gusto de todos, es prácticamente imposible contar con constructores para todos los casos.


Para aliviar estos problemas, Microsoft nos proporciona los inicializadores automáticos de objetos, que ya los hemos visto en posts anteriores, ya que hacen que el código sea un poco más claro.

Persona persona1 = new Persona { DNI = "123456789A", Nombre = "Walter", Edad = 54 };
Persona persona2 = new Persona { DNI = "000000001A", Nombre = "Angel" , Edad = 25 };


La forma de uso es muy sencilla, simplemente después de la llamada al new, abrimos y cerramos ‘{}’ y en su interior hacemos la asignación de las propiedades o campos públicos que creamos oportunos.


Si revisamos la clase Persona, la misma que utilizamos en el ejemplo anterior, un poquito más arriba, ésta carece de constructor codificado, aunque eso no quiere decir que no tenga de forma implícita, ya que Framework en este caso añade un constructor por defecto sin parámetros, que es al que están llamando las dos sentencias de ejemplo. Una forma más clara de realizar la llamada hubiera sido la siguiente:

Persona persona1 = new Persona() { DNI = "123456789A", Nombre = "Walter", Edad = 54 };


Como se puede observar hemos añadido ‘()’ después del tipo, indicando de manera clara la llamada a su constructor sin parámetros. En esto como en otras tantas facetas del CLR, en caso de no tener parámetros se pueden omitir los paréntesis.


Este tipo de inicialización no elimina la especialización o limitación de inicialización de clase. Aunque tengamos la libertad de asignar las propiedades públicas a nuestro gusto, si añadimos un único constructor que obligue a facilitar el DNI en cada creación de un tipo Persona, mediante un constructor diseñado para ello:

public class Persona
{
            
    public Persona(string dni)
    {
        this.DNI = dni;
    }

    public string DNI    { get; set; } 
    public string Nombre { get; set; } 
    public int    Edad   { get; set; }
}

No podríamos hacer uso ninguna de las llamadas anteriores, ya que sería obligatorio cubrir las necesidades de este constructor:









Harías uso explícito de su constructor:

Persona persona1 = new Persona ("123456789A") { Nombre = "Walter", Edad = 54 };



Inicializadores de Colecciones

En esencia la manera de inicializar de manera automática nuestras colecciones, es bastante similar a lo que veíamos con anterioridad en las clases, pero en vez de indicando los valores para sus propiedades, indicando los valores para sus elementos.

Tenemos 2 tipos disponibles de inicializadores:

ARRAYS

Tiene una forma más contraída de definición y no hace falte ni indicar el tipo después del igual:

string[] strings = {"uno", "dos"};
int[]    ints    = { 1, 2 };
object[] objetos = {"uno", 2};



COLECCIONES


Es básicamente igual que para los arrays pero indicando el new tipo después del igual:

List<string> strings = new List<string>() {"uno", "dos"};
HashSet<int> ints    = new HashSet<int>() { 1, 2 };