jueves, 22 de mayo de 2014

Tipos Genéricos en C# - Parte 5: Interfaces Genéricas

Tabla de Contenido

0. Introducción
1. ¿Qué es una Interfaz Genérica?
1.1 Declaración de una interfaz genérica
1.2 Ejemplo de una interfaz genérica
2. Restricciones sobres los Parámetros de Tipo en una Interfaz Genérica
2.1 Lista completa de restricciones
3. Ejemplo Completo de Interfaces Genéricas
4. Conclusiones
5. Glosario
6. Literatura & Enlaces

0. Introducción

Continuamos con la serie de artículos de tipos genéricos en C#. En esta oportunidad empezamos por hablar más a fondo de las interfaces genéricas. Veremos que este mecanismo permite crear clases genéricas para colecciones, o para clases genéricas que representan elementos en una colección. Prepararemos un ejemplo en donde podamos poner en acción varios de los nuevos conceptos descubiertos a largo de esta entrada.

1. ¿Qué es una Interfaz Genérica?

En esencia, una interfaz genérica presta los mismos servicios que una interfaz no-genérica (como vimos en la serie dedicada a este tipo: Introducción a las Interfaces), es decir, la de proveer un contrato con funciones (métodos, propiedades, e.g.) abstractos; sin embargo, una clase genérica cuenta con un nuevo (el único) elemento: parámetros por tipo. A través, de una interfaz genérica podemos ampliar la generalidad de los tipos de datos que definimos en nuestro modelo del mundo del problema.

Al igual que en las clases genéricas, la generalización también ayuda mejorar el desempeño, la seguridad de tipos, y la reusabilidad de código. (Lo veremos en los ejemplos que presentaremos más adelante).

1.1 Declaración de una interfaz genérica

Para declarar una interfaz genérica seguimos las mismas convenciones de una interfaz no-genérica:

{modificador de acceso} interface {nombre de la interfaz} <T [,T...]> {restricciones}

Vemos que además, agregamos la sintaxis para los parámetros o argumentos de tipo, y, sus respectivas restricciones: <T [,T...]> {restricciones}

Descripción puntual:
  • {modificador de acceso}: Modificador de acceso para la interfaz (cfr. Modificadores de Acceso en C#)
  • {nombre de la interfaz}: Identificador o nombre de la interfaz. Debe seguir las reglas de nomenclatura de identificadores.
  • <T [,T...]>: Lista de parámetros o argumentos de tipo.
  • {restricciones}: Las restricciones de los argumentos de tipo con otros argumentos de tipo o tipos concretos de la biblioteca de clases del Framework o las propias creadas por el programadores.
Veamos un ejemplo concreto de una interfaz genérica:

public interface IOperacioensBinarias<T> { }

O con varios parámetros de tipo:

public interface IDiccionario<TLlave, TValor> { }

1.2 Ejemplo de una interfaz genérica

A continuación un ejemplo más extenso de una interfaz genérica para demostrar los conceptos anteriores:


Esta interfaz -IOperacionesBinarias<T>- tiene definido un argumento de tipo (T), y cuatro operaciones:
  • T Sumar(T a, T b);
  • T Restar(T a, T b);
  • T Multiplicar(T a, T b);
  • T Dividir(T a, T b);
Todas las anteriores, utilizan como argumento y tipo de retorno el argumento de tipo definido en la firma de la interfaz: T. Esencialmente, lo que esto nos va a permitir es realizar cualquiera de estas operaciones binarias sobre cualquier de los tipos de datos que portan las operaciones aritméticas fundamentales.

Creemos dos clases concretas que implementen esta interfaz y sus cuatro métodos:

Archivo AritmeticaBasica.cs:

En la línea 19 la clase AritmeticaBasica implementa la interfaz IOperacionesBinarias con el argumento (parámetro) de tipo double. Esto indica que la clase concreta AritmeticaBasica implementará métodos que sumen números de punto flotante (osea, double).

Pudimos haber hecho esto para el tipo entero de 32 bits (int):

public class AritmeticaBasica : IOperacionesBinarias<int>

2. Restricciones sobre los Parámetros de Tipo de una Interfaz

Una interfaz genérica puede contener un parámetro de tipo al que se le puede asignar una o más restricciones.

Por ejemplo la clase genérica Pila puede implementar la interfaz de comparación y de enumeración de elementos: System.IComparable<T> [6]System.Collections.Generic.IEnumerable<T> [7], usando la palabra clave contextual. Así:

public class Pila<T> where T : System.IComporable<T>, IEnumerable<T> { }

2.1 Lista completa de restricciones

En la Figura 1 [8] se enlistan las 6 clases de restricciones para tipos de parámetros (estos también aplican para los parámetros de tipo de una clase genérica -cfr. Tipos Genéricos en C#: Clases Genéricas-).
Seis tipos de restricciones para los parámetros (argumentos) de tipo.
Figura 1. Seis tipos de restricciones para los parámetros (argumentos) de tipo [8].

3. Ejemplo Completo de Interfaces Genéricas

Crearemos la siguiente jerarquía de tipos (interfaces, y clases genéricas) para demostrar el potencial de las interfaces genéricas.

La Figura 2 muestra la jerarquía de tipos para este ejemplo.
Jerarquía de tipos a implementar.
Figura 2. Jerarquía de tipos a implementar.

[Nota: Omito la descripción del código. El código fuente del archivo UsoInterfacesGenericas.cs posee descripción.]

4. Conclusiones

Las interfaces genéricas son una construcción importante que fomenta la reusabilidad a través de la generalización de tipos. Exploramos la declaración de una interfaz genérica (que por supuesto, para todos fue sencillo, pues sólo bastó con exponer la construcción de parámetros o argumentos de tipo: <T>). El ejemplo en la sección 3 nos enseña todos los conceptos presentados, además de situarnos en un caso preciso de la aplicación de interfaces concreatas.

5. Glosario

  • Argumentos de tipo
  • Clase genérica
  • Herencia
  • Implementación
  • Interfaz genérica
  • Generalización
  • Parámetros de tipo

6. 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]: Generic Interfaces (C# Programming Guide) - http://msdn.microsoft.com/en-us/library/kwtft8ak.aspx
[3]: C# Programming: Creating and Using a Generic Interface - http://www.functionx.com/csharp/interfaces/cugi.htm
[4]: Interfaces en C# - Parte 1 - http://ortizol.blogspot.com/2014/05/interfaces-en-c-parte-1.html
[5]: Modificadores de Acceso en C# | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/04/modificadores-de-acceso-en-c.html
[6]: IComparable(T) Interface (System) - http://msdn.microsoft.com/en-us/library/4d7sx9hd(v=vs.110).aspx
[7]: IEnumerable(T) Interface (System.Collections.Generic) - http://msdn.microsoft.com/en-us/library/9eekhta0(v=vs.110).aspx
[8]: Constraints on Type Parameters (C# Programming Guide) - http://msdn.microsoft.com/en-us/library/d5x73970.aspx


J

No hay comentarios:

Publicar un comentario

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