Genericidad en C#. Ejemplos

Jun 6, 2010 Programacion Tutoriales C# 5 comentarios

Si no sabes que es la genericidad, te aconsejo que prestes atención, porque sin duda esta nueva característica, que se presenta a partir de la versión 2.0 del Framework .Net, te cambiará totalmente la forma de ver las cosas y te facilitará la vida a la hora de crear un programa con C#.

¿Qué es la genericidad?

Primero lo primero. La genericidad nos permite pasar un tipo genérico (o más), como parámetro a un método, clase, estructura o interfaz. O sea, este nuevo tipo (que llamaremos <T>), viene a sustituir al tipo object, que es usado sobre todo en estructuras de propósito general, como son los arraylist, pilas (stack), colas (queue) y otras que usamos frecuentemente, en las cuales todos los elementos deben ser de un mismo tipo. Por ejemplo, en una lista de números, en la que no queremos que hayan datos de tipo strings o char, solo de tipo int. Ahora se preguntarán ¿Por qué sustituir el tipo Object?

Recuerden que todos los tipos en C# (int, long, string, char, etc) heredan de la clase Object, lo cual es una ventaja para algunas cosas, pero a la vez es un problema a la hora de chequear el tipo de los elementos que se insertan en estas estructuras, ya que no hay una forma rápida y eficaz de verificar que todos los elementos sean del mismo tipo, para controlar esto, tendríamos que castear* cada vez que queramos obtener un valor de dicha estructura, lo cual puede llevar a errores, por no mencionar que es algo muy pesado, incómodo de programar y hay una gran posibilidad de errores en tiempo de ejecución.

Al usar genericidad también tenemos que tener en cuenta algunos cambios (para bien) en nuestra forma de programar, pero es mejor verlo en la práctica, veamos un ejemplo: Supongamos que queremos crear una clase con un método o función que nos devuelva el menor de dos valores de un mismo tipo. Utilizando la genericidad, tendríamos algo así:

class Ejemplo //T es el tipo de dato genérico
{
    //Método que devuelve un elemento de tipo T que es el mínimo
    //entre el elemento x y el elemento <em>y</em>
    T Minimo(T x, T y)
    {
       if(x &lt; y)
          return x;
       else
          return y;
    }
 
}

Ahora veamos qué pasa cuando invocamos este método:

//Supongamos que tenemos una clase Figura
Figura f1 = new Figura();
Figura f2 = new Figura();
Ejemplo ej = new Ejemplo();
Figura min = ej.Minimo(f1, f2);

Este código ni siquiera se ejecutaría, y dará un error en tiempo de compilación en la línea marcada de la clase Ejemplo<T> donde T es la clase Figura, ya que en ninguna parte especificamos cuando una instancia de Figura es menor, mayor o igual que otra, sin embargo, para el tipo int esto no supondría ningún problema verdad?

¿Qué quiere decir esto?

Cuando usemos genericidad tenemos que ser mucho más cuidadosos y formales cuando programemos, lo cual no es una mala práctica y es bueno ir acostumbrándose. Ahora arreglemos la clase Ejemplo para que el método Minimo(T x, T y) funcione con cualquier tipo de dato en general (que se pueda comparar):

class Ejemplo where T: IComparable;
{
    T Minimo(T x, T y)
    {
        int c = x.CompareTo(y);
        if(c&lt;0)
            return x;
        else
            return y;
    }
}

Ahora ya especificamos que T es un tipo que debe implementar la interfaz IComparable<T>. En otras palabras, obligamos a que los elementos de tipo T se pueden comparar entre ellos, ya que en otro caso, hallar el mínimo pierde el sentido. En estos casos, se utiliza la palabra reservada where: y a continuación todas las restricciones que debe cumplir T, separadas por coma.

Entonces usamos el método CompareTo que debe implementar toda clase T que sea IComparable para saber cuál es el menor elemento. Este método deberá devolver 0 si x=y, 1 si x>y,-1 si x<y. Por tanto, el resultado de ejecutar Minimo, depende completamente de cómo implementemos el método CompareTo(). Por ejemplo, si tenemos la clase Figura:

class Figura: IComparable
{
    //Supongamos que tenemos estos métodos implementados
    public long Area();
    public long Perimetro();
 
    //Ahora implementamos el método <em>CompareTo</em>
    public int CompareTo(Figura f)
    {
        if(this.Area&gt;f.Area)
            return 1;
        else if(this.Area

En este caso, decidimos que una Figura es mayor que otra, en función del área, pero podemos definir que se comparen por el diámetro, por el perímetro, etc. Noten que aquí si podemos usar los operadores binarios dentro del CompareTo, ya que en este caso comparamos implícitamente elementos de tipo long, que son IComparables por defecto. Ya vas notando algunas ventajas de usar genericidad?

Ahora en un mismo método Mínimo, podemos devolver el elemento menor de cualquier tipo de dato que se pueda comparar, noten que este método nos servirá para Int, String, Long, Figuras, Personas y toda clase o tipo que implemente la interfaz IComparable.

Les dejo dos implementación de la clase Queue<T>, que es una cola con algunos métodos genéricos. En una de las implementaciones uso arrays, y en la otra colas enlazables. No lo he probado muy bien, pero funcionaba hace dos años cuando la implementé, jeje.

Veremos algunas otras cosas que podemos hacer con la genericidad en la segunda entrega de este tutorial, la semana próxima. Cualquier duda en los comentarios.

Descarga aquí el archivo en .zip:  Cola en C#

Compartir:

Relacionados

algunos artículos que te pueden interesar

5 comentarios

Forma parte de nuestra discusión y síguela de cerca

Mil gracias por la información, estoy empezando a estudiar pues este programa para poderlo trabajar mejor y pues esto que expones me ayudara increible, quedare en espera de la siguiente parte.

Saludos

Autor: Felipe | Fecha: Jun 10, 2010.

no me quedo claro algo, recien estoy empezando en esto y tengo mis dudas. Tengo que si o si definir una clase (como tu haz definido la clase Ejemplo) que sea tipo T donde T implemente la interfaz IComparable?

Autor: Noelia | Fecha: Sep 14, 2010.

[...] Nota: Si no estás familiarizado con la notación “T x” utilizada para clases genéricas, puedes leer aquí sobre genericidad en C#. [...]

Autor: Arboles en C#. Definiciones, funciones y código | puntopeek | Fecha: Nov 28, 2010.

muy bueno, bien explicado

Autor: Elmer Estrada | Fecha: Sep 28, 2011.

Esta muy breve la explicacion, pero es buena.
Falta checar bien las ventajas de los genericos

Autor: Antonio | Fecha: Ene 28, 2014.

Escribe tu comentario

Requerido.

Requerido. No público.

Si tienes alguno.