Un ejemplo de Generics

Fecha: 09/Oct/2004 (8 de Octubre 2004)
Autor: Misael Monterroca mmonterroca@neo-mx.com

 


Todo elemento agregado a un arraylist de hecho a cualquier colección (a menos que creemos nuestra propia colección derivando de CollecionBase) es almacenado como un objeto (System.Object) con lo cual siempre obligamos a que se este haciendo un boxing y unboxing del tipo que queramos agregar.

         ArrayList listaInt = new ArrayList();

            for (int intN = 0; intN <= 10; intN++)

            {

                listaInt.Add(intN); //Se almacenara como objeto

            }

            int valor = listaInt[0];

Si realizáramos la compilación de este código el compilador nos dará un error en la línea, int valor = listaInt[0];
Ya que un objeto no se puede convertir explícitamente a un tipo Int

Para poder realizar la compilación necesitamos convertir explícitamente el elemento a un tipo Int, una vez realizado esto, nuestro ejemplo compilara. Al realizar este proceso estamos haciendo el Boxing de Integer a System.Object y el unboxing de System.Object a Integer

int valor = (int) listaInt[0];

Esto nos da pie a tener otro tipo de errores no contemplados dentro del desarrollo de nuestra aplicación, ya que como vimos el ArrayList nos permite almacenar cualquier tipo de dato llegando a tener un caso como este.

ArrayList lista = new ArrayList();

            lista.Add(1);

            lista.Add(2);

            lista.Add("3");

            lista.Add(4);

            foreach (int elemento in lista)

            {

                Console.WriteLine("Elemento {0}",elemento);

            }

Este ejemplo no tendra errores al momento de la compilación, pero no sucedera lo mismo al momento de la ejecución, podran notar que el tercer elemento es de un tipo String, los demás elementos podremos considerarlos como Int, al realizar el barrido de los elementos especificamos que nuestra variable es de tipo Int, pero al llegar al elemento 3 la aplicación incurrira en una exepción ya que el elemento 3 como habiamos dicho es de tipo String

El verdadero problema es que esto no lo detectaremos hasta que nuestra aplicación este en ejecución ya que es muy común que almacenemos nuestros datos a partir de objetos de entrada, como textboxes, combos etc. sin hacer el Cast correspondiente al tipo de dato que en su momento necesitemos utilizar

Aquí es donde se puede ver una utilización de generics al poder crear una clase que funcionara como un Array pero al cual forzosamente es inicializado con el tipo de dato especifico con el cual queramos trabajar.

Para este caso se creo una clase llamada ArrayGenerics (el código de la clase se muestra al final) la cual será inicializada con el tipo de datos que necesitemos en nuestro caso es un Integer (Int) el cual es especificado inmediatamente después del nombre de la clase , al ser inicializada con un tipo especifico esta clase no admitirá ningún tipo de dato diferente al especificado en nuestro caso solo admitirá tipos de datos Int

ArrayGenerics<int> listaGen = new ArrayGenerics<int>();

            listaGen.Agregar(1);

            listaGen.Agregar(2);

            listaGen.Agregar(3);

            foreach (int elemento in listaGen)

            {

                Console.WriteLine("Elemento {0}", elemento);

            }

Al haber sido inicializado con un tipo de dato especifico nos estamo olvidando de Boxing y Unboxing ya que el dato almacenado siempre será del tipo solicitado.

Si al ejemplo anterior quisieramos agregarle un tipo diferente, por ejemplo un string “3” 

ArrayGenerics<int> listaGen = new ArrayGenerics<int>();

            listaGen.Agregar(1);

            listaGen.Agregar(2);

            listaGen.Agregar(“3”);

este código nos generara el siguiente error:

El cual nos indica un mensaje de error el cual nos indica que no se puede convertir explícitamente un tipo de dato string en un int, una de las ventajas es que este error nos lo dara en tiempo de compilación con lo cual podremos siempre evitar excepciones en tiempo de ejecución

Como mencionabamos, generic toma cualquier tipo de dato, en este caso utilizaremos la misma clase pero ahora para crear un arreglo de controles TextBox.

ArrayGenerics<TextBox> listaGen = new ArrayGenerics<TextBox>();

            listaGen.Agregar(new TextBox);

            listaGen.Agregar(new TextBox);

            listaGen.Agregar(new TextBox);

La única diferencia que tiene contra una clase “común” es la declaración de la misma, a la cual se le incluye inmediatamente después del nombre de la clase la declaración de un nombre de datos genérico en nuestro caso el cual cuando la clase sea instancía sera reemplazado por el tipo especificado en ella.

ArrayGenerics<TextBox> listaGen = new ArrayGenerics<TextBox>();

En ejecución <TipoDato>   será sustituido por <TextBox>

El código completo de la clase ArrayGenerics esta al final del a página ,aqui solo dejo el comienzo de la clase para especificar como se declara una clase Generics

public class ArrayGenerics<TipoDato>    //Definición de la clase con el <TipoDato> que sera el que substituira con el tipo que se declare en la clase

    {



ir al índice

Fichero con el código de ejemplo: neo_mx_EjemploGenerics - 10 KB