Developer's Diary

29 marzo, 2011

Curso de C# – Colecciones Genericas

Buenas de nuevo.

Antes de comenzar con el último punto dentro de nuestro Curso de C#, el acceso a Bases de datos. Quería hacer también un pequeño corto, para mostrar las colecciones genericas y como aumentan la capacidad del programador cuando se usan.

Cuando comencé a programar, solamente usaba arrays y matrices para trabajar con muchos datos a la vez. Pero en el momento que descubrí todos los tipos de colecciones que existían y la facilidad de usarlos, no dude ni un segundo en usarlo. Además, esta completamente probado que la eficiencia de estos es mucho mayor, tanto en ahorro de memoria, como en procesamiento, como en facilidad para el desarrollador.

Las colecciones genéricas aparecen por primera vez en el Framework 2.0. Aunque existen al menos unos diez tipos de colecciones, en este post vamos a hablar de tres, anteriormente, también existían colecciones pero el inconveniente que tenían era, que se trataban de colecciones que almacenaban el tipo de dato Object, por lo tanto la perdida de memoria y tiempo de proceso se debe a este hecho, me explico.

Como es un Object entra el proceso de Boxing y Unboxing. A la gente nueva en el desarrollo le sonara algo raro. Aunque ya lo habremos mencionado en alguna otra ocasión en .Net todos las clases heredan de la clase primaria que es Object, incluso los tipos de datos, aunque no es del todo correcto. Por lo tanto el proceso de Boxing y Unboxing es el siguiente. Se explica de una manera sencilla. Cuando realizamos el proceso de Boxing se introduce nuestro dato en una caja, en este caso la caja es Object, por eso las colecciones que no son genericas, permiten introducir cualquier tipo de objeto.

Sin embargo, el proceso de Unboxing, desenvuelve el anterior objeto metido en una caja, debemos tener mucho cuidado con este proceso, porque si este proceso que realizamos no contiene el objeto que esperamos se puede producir una excepción.

Pongamos un ejemplo aplicado a la vida cotidiana. Tenemos una caja, en donde meteremos manzanas, pero sin querer introducimos también una pera. Ahora mandamos esa caja a un frutero, cuando el frutero compruebe que dentro de la caja de manzanas ahí una pera, podría molestarse.

Eso es lo que ocurre con el fenomeno de boxing y unboxing.

Esto no ocurre con las colecciones genericas, una coleccion generica solo acepta objetos del tipo del cual hayamos creado la colección en cuestión. Si la caja es de manzanas, solo se podrán meter manzanas. Con las colecciones no genericas, no ocurría esto, se podían introducir manzanas, peras e incluso pelotas, pero después podría haber confusión. Además de que el proceso en cuestión demora mucho la tarea.

Las colecciones genericas que vamos a ver en este post, son tres, como ya indicábamos arriba y tienen su homonimos dentro de las colecciones simples, que solo aceptan objetos. Los tipos son List, Dictionary y Stack.

List

Las listas son una de las colecciones más convencionales que podemos usar. Estas nos permiten acceder a cualquier elemento que exista en la misma, además de poder trabajar con la misma correctamente. Para acceder a un objeto en cuestión, podemos acceder a él mediante su índice.  Su homonimo no genérico es el tipo ArrayList.

Siempre que declaramos una lista generica o cualquier otra colección genérica debemos indicar de que tipo de objeto va a tratarse la lista, de la siguiente manera:

List<string> listadestring = new List<string>();

En este caso hemos creado una lista de objetos que albergará string. Pero también podemos crear una que acepte enteros o cualquier otro tipo de objeto. También podemos crear una lista de listas, ya que la lista genérica en si, también es un objeto como en el siguiente ejemplo:

List<List<string>> listadelistadestring = new List<List<string>>();

En este caso, hemos creado una lista que albergara a su vez listas de string, este segundo ejemplo puede resultar algo lioso, pero es para comprobar que podemos tener listas al estilo de una matriz por así decirlo.

Este tipo de objetos heredan de la interfaz IList, por lo que cualquier lista posee unos determinados métodos en todas las listas. Los métodos más interesantes son los siguientes:

Add(objeto)

Nos permitirá añadir un objeto, el parametro debe de ser del mismo tipo del cual hemos creado la lista, en el caso que veíamos antes de string.

AddRange(IEnumerable<objeto>)

Existen muchos tipos de objetos que también heredan de la interfaz IEnumerable, como las colecciones por ejemplo, esto nos permite introducir un grupo de elementos siempre y cuando pasemos como parametro un objeto que herede de la interfaz IEnumerable del tipo de objeto que también es nuestra colección.

Clear()

Este método, nos permite limpiar toda la lista, para dejarla vacía.

Contains(objeto)

Mediante contains, recuperaremos un booleano indicándonos si el objeto del mismo tipo de la colección se encuentra dentro de nuestra lista, True o en caso contrario no existe. False.

Count

Aunque se trata de una propiedad, Count, nos permite comprobar recuperando un entero, cuanto es el número de elementos que tenemos dentro de la lista.

Remove(objeto)

Con Remove, podemos eleminar un objeto de nuestra lista, siempre que este se encuentre dentro de la misma.

ToArray()

Dictionary

Este método, me resulta bastante útil. Ya que me siento más cómodo trabajando con listas, antes de que con arrays convencionales. Usando este método, recuperamos un array del mismo tipo de la lista. En muchas ocasiones hay métodos a los debemos devolver un array. Por lo tanto si usamos una lista genérica que puede resultarnos mucho más cómodo en su uso y posteriormente usamos este método para recuperar un array es mucho más útil.

Existen mucho más métodos, que nos pueden dar una gran funcionalidad dentro de la lista, pero son métodos más complejos a los cuales se le tienen que pasar procedimientos, ya haremos otra entrada para hablar de ellos, porque puede dar mucha funcionalidad a nuestra aplicación.

Nuestra segunda colección genérica que nos puede ser de gran utilidad dentro de nuestras aplicaciones es la de tipo Dictionary. Esta recibe dos parametros genericos. Dentro de las colecciones convencionales, su homonimo es el HashTable, en el caso de la HashTable teníamos también dos objetos, uno de tipo string y el segundo de tipo object. El primer objeto sirve de Key, este tipo de colecciones resultan útiles, para el desarrollador, ya que en vez de tener que buscar un elemento mediante su valor de índice, podemos localizarlo mediante su Key.

A diferencia de la HashTable, las colecciones de tipo Dictionary permiten elegir el tipo de objeto que será Key y cual será el que almacene. Es evidente que el objeto que haga la función de Key, debe ser un tipo de objeto no demasiado pesado ya que las búsquedas se harán en base a él.

Otro detalle de importancia al usar este tipo de colecciones es que nunca se pueden repetir la Key, por lo tanto si agregamos dos entradas con el mismo valor en la Key, se producirá una excepción. Creemos por ejemplo de un Dictionary para almacenar cumpleaños, por lo tanto nuestra Key será un string y nuestro objeto será un DateTime. La instanciación sería así:

Dictionary<string, DateTime> fechasdecumpleanos = new Dictionary<string, DateTime>();

Los métodos que podemos considerar interesantes, son los mismos que podemos encontrar dentro de una lista, pero tenemos dos detalles que la diferencían.

El primero es que no se pueden introducir dos entradas con el mismo valor en la Key, en este caso el método Add, acepta dos parametros, en nuestro ejemplo string y DateTime. Si el objeto de string, si añadiesemos dos filas con el valor dentro de string que fuesen “Cumpleaños de Patri” , al añadir el segundo valor se produciría una excepción.

Lo segundo, es la capacidad que obtenemos para la búsqueda de elementos de una manera más sencilla. Es decir, si en una lista solo podíamos buscar mediante la posición de la lista, es decir, mediante un entero. Como en el siguiente ejemplo:

lista[5] Así accederiamos al sexto elemento de la lista, debemos tener en cuenta que al igual que en los arrays, el primer elemento es el valor O.

En el caso de un dictionary, buscaríamos un elemento debido a su array, en el caso del ejemplo mediante una cadena de texto.

fechasdecumpleanos[“Cumpleaños de Patri”]

Esto puede resultar mucho más cómodo, además de más rapido y eficiente.

También debemos mencionar, que podemos acceder a las Keys solamente mediante la propiedad Keys del Dictionary y los valores de Objeto mediante la propiedad Values.

Por último, un solo elemento del dictionary es el objeto de tipo KeyValuePair, este también es un objeto genérico por lo que también contiene los elementos que hayamos declarado dentro del Dictionary.

Stack

 

La Stack o también conocida en español Pila. Es uno de los tipos de colecciones más primigenios que pueden existir. Su acceso es mucho más rápido y sencillo que otras colecciones, pero también tenemos que indicar que su complejidad es menor. Solo podemos acceder al último objeto agregado y su capacidad está más limitada que las colecciones anteriores, sin embargo, también es mucho más rápida y eficiente, al no requerir de tanta memoria.

 

La declaración de una pila es muy similar a la lista, en este caso haremos un ejemplo de una pila que solo acepte enteros.

 

Stack<int> pilaenteros = new Stack<int>();

 

Para agregar elementos tenemos que utilizar el siguiente método Push, con un parametro que será igual al tipo de objeto. Para eliminar elementos de nuestra pila usaremos el método Pop, este retorna un tipo de objeto igual al de la pila, de hecho el elemento que hayamos removido.

 

Una pila no, nos resulta útil por ejemplo si queremos acceder a un objeto que se encuentra en mitad de la misma, porque tendremos que ir eliminando objeto por objeto de la misma, hasta alcanzar este.

 

No obstante nos puede ser útil para muchas otras cosas, por ejemplo, si queremos introducir un grupo de peticiones dentro de nuestra aplicación a otro módulo de la misma por ejemplo, estas se van agregando a la pila y se van eliminando según el módulo se vaya encontrando libre o para introducir una cantidad de datos que posteriormente vamos ir trabajando con él.

 

Bien, hasta aquí, esta pequeña introducción de las colecciones genéricas. Acostumbrarnos a usarlas, nos puede permitir un desarrollo mucho más ágil y eficiente dentro de nuestras aplicaciones. Ya que resultan menos engorrosas para su utilización dentro de una aplicación, a difierencia de las colecciones no genéricas o el uso de arrays.

 

Éxisten muchas más colecciones, que puedes descubrir tu mismo. Aunque a simple vista todas puedes cubrir las necesidades dentro de un desarrollo, puedes encontrarte con la incertidumbre de necesitar una funcionalidad más especifica, en ese caso puedes crear tus propias colecciones ya que todas proceden de interfaces, además de poder heredar completamente cada una de ellas.

 

Hasta aquí el curso de hoy, en la siguiente entrega comenzaremos con las bases de datos.

 

Un saludo!

Anuncios

5 comentarios »

  1. Muchas gracias, esta información me fué de gran ayuda para un programa que estoy realizando

    Comentario por usuario — 30 agosto, 2011 @ 5:16 PM

    • Me alegro de que te haya sido de utilidad. Si te surge alguna duda que no encuentres la solución solo tienes que decirlo. Un saludo.

      Comentario por 3nk1 — 30 agosto, 2011 @ 8:04 PM

      • pregunta. en que casos me podrias decir que es necesario o bueno, utilizar dictionary??? gracias x todo esta muy claro. pero se que me preguntaran sobre casos de uso. me das una lus de donde lo es necesario.

        Comentario por Max — 25 marzo, 2014 @ 10:45 PM

  2. Muy bien explicado. Ya sólo faltaría una aproximación a la interfaz IEnumerable…

    Comentario por Vicente — 12 enero, 2012 @ 4:52 PM

    • Gracias.
      Explicaré en otro post lo que nos comentas.

      Un saludo.

      Comentario por 3nk1 — 13 enero, 2012 @ 5:11 PM


RSS feed for comments on this post. TrackBack URI

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: