martes, 12 de agosto de 2014

Inicializadores de Colecciones y Objetos en C#

Índice

0. Introducción
1. ¿Qué es un Inicializador?
2. Inicializadores de Objetos
2.1 Tipos anónimos
3. Inicializadores de Colecciones
3.1 Colecciones no-genéricas
3.2 Colecciones genéricas
4. Ejemplo de Uso (Colecciones Genéricas)
5. Conclusiones
6. Glosario
7. Literatura & Enlaces

0. Introducción

En el artículos C# previo aprendimos a crear secuencia de valores a partir de las interfaces IEnumerator y IEnumerable (ambas en sus versiones no-genérica y genérica); conectado con este conocimiento previo, el desarrollo que haremos a continuación consistirá en la comprensión de la inicialización de elementos de una colección: inicializadores de colección. Por otro lado, veremos que los inicializadores también pueden ser utilizado en tipos de datos simples por medio del uso de una sintaxis sencilla y cómoda.

1. ¿Qué es un Inicializador?

A partir de la versión 3.0 de C# la creación de una instancia de un objeto o de una colección se puede realizar por medio del uso de un inicializador. Este inicializador comprende la creación de instancias y/o la asignación de valores a propiedades. Este método método de inicialización evita la invocación explícita de un constructor o cualquier otro miembro de asignación de valores al estado del objeto recién creado. Un ejemplo de uso práctico comprende el siguiente código C#:


Creamos una clase con dos propiedades auto-implementadas (cfr. Definición de una Propiedad Autp-Implementada):


public class Persona
{
// Propiedades auto-implementadas:
public String Nombre { get; set; }
public String Apellido { get; set; }
}

A continuación creamos una instancia de la clase Persona e inicializamos cada propiedad a través de un inicializador:

Persona persona = new Persona { Nombre = "Alexander", Apellido = "Bell" };


Esta instrucción invoca el constructor predeterminado (sin argumentos) de la clase Persona, y además asigna los valores Alexander y Bell como cadenas de caracteres a las propiedades Nombre y Apellido, respectivamente.



Después de esta breve introducción veamos con más detalle, el uso de inicializadores en tipos anónimos y, desde luego, en colecciones no-genéricas y genéricas.

2. Inicializadores de Objetos

En la sección inmediatamente anterior vimos cómo usar la lista de inicialización para la asignación de valores a propiedades de una clase de objeto (la clase Persona), claro que se trata de una manera más cómoda a tener que hacer esto:

Persona persona = new Persona();

persona.Nombre = "Alexander";
persona.Apellido = "Bell";

Evidentemente, los efectos sobre el estado del objeto serán los mismos, iterum, la sintaxis de inicializadores es más ágil y breve.

2.1 Tipos anónimos

Otra de las particularidades importantes del uso de inicializadores comprende las expresiones de consulta LINQ. En este caso se recurre a la declaración de tipos anónimos para la construcción de los elementos resultantes de una consulta a partir de la validación de un predicado o una proyección de campos simple. Comprendamos esto con este ejemplo sintáctico básico:

var infoProductos =
from producto in productos
select new { producto.Nombre, producto.ValorUnitario };

productos no es más que un grupo de objetos de tipo Producto, a partir de este grupo se crea un subgrupo (a partir de objetos anónimos [cfr. Creación de un Tipo Anónimo]) que comprenda sólo los campos Nombre y ValorUnitario. Para lograr lo anterior, recurrimos al uso de un inicializador en el cual se enumera sólo la proyección de campos necesarios para la creación del tipo anónimo.

Continuando, el resultado de esta consulta LINQ lo podemos iterar (o recorrer) con el uso del ciclo foreach:

foreach (var producto in infoProductos)
{
Console.WriteLine ("Nombre: {0} - Precio unitario: {1}",
producto.Nombre,
producto.ValorUnitario
);
}

3. Inicializadores de Colecciones

Los inicializadores también pueden ser usados tanto en colecciones genéricas como en colecciones no genéricas. En las sub-secciones que vienen a continuación comprenderemos como crear una lista de objetos y agregar elementos a través de este método sintáctico.

3.1 Colecciones no-genéricas

A partir de la clase estándar Persona:

public class Persona
{
// Propiedades auto-implementadas:
public String Nombre { get; set; }
public String Apellido { get; set; }
}


podemos crear un objeto List con elementos Persona usando un inicializador. Así:


List listaPersonas = new List()
{
new Persona { Nombre = "Alexander", Apellido = "Bell" },
new Persona { Nombre = "Alan", Apellido = "Turin" }
};


O de lo contrario, pudimos haber utilizado el viejo enfoque anterior a C# 3.0:


List listaPersonas = new List();

Persona persona1 = new Persona();
persona1.Nombre = "Alexander";
persona1.Apellido = "Bell";
listaPersonas.Add(persona1);

Persona persona2 = new Persona();
persona2.Nombre = "Alan";
persona2.Apellido = "Turin";
listaPersonas.Add(persona2);

Queda resaltado que el uso de inicializadores resulta un enfoque o práctica más cómodo.


Vale mencionar que podemos usar los inicializadores con todas las estructuras de datos (o colecciones) que implementen la interfaz IEnumerable [8].

3.2 Colecciones genéricas

Para todas las colecciones genéricas (tipos que pertenecen al nombre de espacio System.Collections.Generic) que implementen la interfaz genérica IEnumerable<T> podemos especificar inicializadores de elementos siguiendo la sintaxis presentada anteriormente:

Una lista de números enteros:

List<int> enteros = new List<int> { 0 + 1, 17 % 3, GenerarEntero() };

-o-

List<int> enteros = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

De forma análoga, podemos proceder con la clase Persona:

List<Persona> listaPersonas = new List<Persona>()
{
new Persona { Nombre = "Alexander", Apellido = "Bell" },
new Persona { Nombre = "Alan", Apellido = "Turin" }
};

Nuevamente, es necesario mencionar que sólo pueden hacer uso de inicializadores de colecciones todas aquellas estructuras de datos que implementen la interfaz genérica IEnumerable<T> [9].

4. Ejemplo de Uso (Colecciones Genéricas)

Para afianzar los conceptos anteriores, creemos un ejemplo de código fuente C#:

Compilación:


  1. csc /target:exe InicializadoresColecciones.cs

Ejecución assembly:


  1. .\InicializadoresColecciones.exe

> Prueba de ejecución (ideone.com).

> Prueba de ejecución (local):
Ejecución assembly InicialidoresColecciones.exe
Figura 1. Ejecución assembly InicialidoresColecciones.exe.

5. Conclusiones

Ha quedado demostrado el uso de inicializadores tanto para tipos de objetos simples como para estructuras de datos (o colecciones). Realmente, este tipo de construcción sintáctica posee un grado de simplicidad significativo respecto al modo estándar (propio de versiones anteriores a C# 3.0). Quedó claro que los inicializadores de colecciones sólo están disponibles para aquellas que implementan las interfaces no-genéricas y genéricas IEnumerable y IEnumerable<T>, respectivamente. En el próximo artículo trabajaremos con iteradores y su semántica.

6. Glosario

  • Colección
  • Consulta
  • Expresión
  • Inicializador
  • LINQ
  • Objeto
  • Tipo genérico
  • Tipo no-genérico

7. Literatura & Enlaces

[1]: C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.
[2]: Object and Collection Initializers (C# Programming Guide) - http://msdn.microsoft.com/en-us/library/bb384062.aspx
[3]: New in C# 3.0: Create and Initialize Collection Objects in One Step.com - http://www.developer.com/net/csharp/article.php/3607421/New-in-C-30-Create-and-Initialize-Collection-Objects-in-One-Step.htm
[4]: Collection initializer# Examples and Tutorials - http://www.dailyfreecode.com/code/collection-initializer-2649.aspx
[5]: Collection Initializers# Tutorial - http://csharp.net-tutorials.com/csharp-3.0/collection-initializers/
[6]: OrtizOL Software (xCSw): Receta No. 1-20 en C#: Definición de una Propiedad Auto-Implementada - http://ortizol.blogspot.com/2014/02/receta-no-1-20-en-c-definicion-de-una.html
[7]: Receta No. 1-18 en C#: Creación de un Tipo Anónimo | OrtizOLón Software (xCSw) - http://ortizol.blogspot.com/2014/02/receta-no-1-18-en-c-creacion-de-un-tipo.html
[8]: IEnumerable Interface (System.Collections) - http://msdn.microsoft.com/en-us/library/system.collections.ienumerable%28v=vs.110%29.aspx
[9]: IEnumerable(T) Interface (System.Collections.Generic) - http://msdn.microsoft.com/en-us/library/9eekhta0%28v=vs.110%29.aspx


J

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.