En este artículo hablaremos sobre los tipos genéricos, mejor conocidos como parámetros genéricos o parámetros de tipo; este es un concepto introducido en Delphi 2009 como una nueva y poderosa característica del lenguaje y hoy en día es muy utilizado por la comunidad desarrolladora debido a las múltiples ventajas que ofrecen a la hora de programar. Ya que es un tema bastante amplio, en este primer artículo haremos una breve introducción para entender un poco su concepto y todo lo que abarca.

¿Qué son Tipos Genéricos?

Los tipos genéricos permiten definir clases y métodos que no especifican el tipo de ciertos miembros de datos en el momento de la definición, sino que lo hace sólo hasta que el código cliente declara y crea una instancia de la clase o del método. El objetivo principal es facilitar la creación de código en su inicio genérico y posteriormente se pueda trabajar con cualquier tipo de datos.

Un ejemplo sencillo para entender un poco el concepto, es el siguiente:

Definimos una clase genérica:

<span class="token keyword">type</span>
    TEjemploGenerica<span class="token operator"><</span>T<span class="token operator">></span> <span class="token operator">=</span> <span class="token keyword">class</span>
    <span class="token keyword">private</span>
    <span class="token keyword">public</span>
      <span class="token keyword">function</span> AdicionaValor<span class="token punctuation">(</span><span class="token keyword">Const</span> AValor<span class="token punctuation">:</span> T<span class="token punctuation">)</span><span class="token punctuation">:</span> T<span class="token punctuation">;</span>
    <span class="token keyword">end</span><span class="token punctuation">;</span>
  
<span class="token keyword">implementation</span>
  <span class="token keyword">function</span> TEjemploGenerica<span class="token operator"><</span>T<span class="token operator">></span><span class="token punctuation">.</span>AdicionaValor<span class="token punctuation">(</span><span class="token keyword">Const</span> AValor<span class="token punctuation">:</span> T<span class="token punctuation">)</span><span class="token punctuation">:</span> T<span class="token punctuation">;</span>
  <span class="token keyword">begin</span>
  <span class="token keyword">Result</span> <span class="token operator">:=</span> AValor <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
  <span class="token keyword">end</span><span class="token punctuation">;</span>

Esta clase contiene un método que permite multiplicar por 2 el valor recibido como parámetro, aunque en el momento de su definición no conocemos aún el tipo de parámetro.

Ahora veamos la instanciación de la clase.

<span class="token keyword">procedure</span> Tform1<span class="token punctuation">.</span>EjecutaClick<span class="token punctuation">(</span>Sender<span class="token punctuation">:</span> Tobject<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span>
  TipoValor <span class="token punctuation">:</span> TejemploGenerica<span class="token operator"><</span>Integer<span class="token operator">></span><span class="token punctuation">;</span>
<span class="token keyword">begin</span>
  TipoValor <span class="token operator">:=</span> TejemploGenerica<span class="token operator"><</span>Integer<span class="token operator">></span><span class="token punctuation">.</span>Create<span class="token punctuation">;</span>
  ShowMessage<span class="token punctuation">(</span>InttoStr<span class="token punctuation">(</span>TipoValor<span class="token punctuation">.</span>AdicionaValor<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//resultado 20</span>
<span class="token keyword">end</span><span class="token punctuation">;</span>

Clases de colecciones genéricas

Delphi agregó un conjunto de colecciones genéricas básicas, además de los tipos genéricos. Estos se encuentran definidos en la unidad System.Generics.Collections y ofrecen un modelo genérico para contenedores vinculados al tipo de datos específico que necesita.

Estas clases se implementan de manera independiente (no heredan de la otra), todas se implementan de manera similar (usando una matriz dinámica) y se asignan a la clase de contenedor no genérica.

  • TList <T>, representa una lista ordenada accesible por un índice. Hereda de TEnumerable que es una clase abstracta heredada por todos los contenedores enumerables. Puede contener una colección genérica de objetos o registros.
  • TThreadList <T>, representa una lista más segura para subprocesos con soporte de bloqueo.
  • TQueue <T> representa una colección de cola genérica (primero en entrar/primero en salir).
  • TStack <T> representa una colección de pila genérica (primero en entrar/primero en salir).
  • TDictionary <TKey, TValue>, define una colección de búsqueda con claves de búsqueda. Permite crear diccionarios bastante potentes con tipos de valores y claves personalizables.
  • TObjectList <T: class> define una colección genérica de objetos.
  • TObjectQueue <T: class> permite definir colas genéricas de objetos (primero en entrar/primero en salir).
  • TObjectStack <T: class> Define pilas genéricas de objetos. (primero en entrar/primero en salir).
  • TObjectDictionary <TKey, TValue> permite definir una colección genérica de objetos propios con claves de búsqueda.
  • TThreadedQueue <T> representa una cola genérica de subprocesos, utiliza el estándar primero en entrar/ primero en salir,  para organizar los datos. Esto es útil cuando se desea tener una cantidad limitada de tiempo en acciones emergentes y push.

Las cuatro principales y más utilizadas son: TList <T>, TQueue <T>, TStack <T> y TDictionary <TKey, Tvalue>. TDictionary, es probablemente el contenedor más rápido si se necesita encontrar un elemento en una lista por valor de clave.

Las colecciones genéricas ofrecen la capacidad de definir contenedores específicos para los tipos de datos dado que necesita usar y dejar que el compilador verifique la compatibilidad del tipo de datos, en lugar de hacer lo mismo en tiempo de ejecución. Esto nos permite tener un código más limpio y legible, aplicaciones más robustas y una ejecución más rápida, dada la menor necesidad de verificaciones en tiempo de ejecución.

Tipos Genéricos: ventajas y desventajas

         Ventajas

  • Su principal utilidad es facilitar la creación de código genérico que pueda trabajar con datos de cualquier tipo. Especialmente útil para crear tipos que actúen como colecciones (pilas, colas, listas, etc.).
  • Se reduce la necesidad de conversión de tipos y la posibilidad de errores en tiempo de ejecución.
  • Evita duplicidad de código.
  • No es necesario escribir código para comprobar el tipo de datos correcto porque esto se hace en tiempo de compilación.

    Desventajas

    En la mayoría de los casos, los contenedores genéricos son algo bueno. Sin embargo, el compilador genera una gran cantidad de código duplicado, por lo que el uso intensivo de genéricos podría resultar en un ejecutable de gran tamaño.

Tipos Genéricos: Conclusiones

Aunque muchos expertos coinciden en que el uso de genéricos puede inflar el tamaño del ejecutable o que es difícil hacer mucho con un parámetro genérico al desconocer su tipo,  son más las ventajas y la utilidad que podemos sacar de ellos, debido a su gran versatilidad en el manejo de los tipos de datos. Los tipos genéricos se puede usar como tipo de un campo, el tipo de una propiedad, el tipo de un parámetro o el valor de retorno de una función, lo que hace que se reduzca la necesidad de gastos en tiempo de ejecución.

¿Necesitas ayuda?

Ahora que nos conoces un poco mejor, si quieres crear sistemas que usen tecnología de vanguardia, ya sabes que forma parte de nuestro día a día y que podemos ayudarte.

Espero que este artículo haya sido interesante y recuerda, si necesitas una consultoría avanzada sobre Delphi puedes contactar con nosotros en nuestro formulario de contacto de Abatic.

Acerca de Emilio Pérez

Programando desde los 9 años y trabajando desde los 19 con Delphi.
Oracle y PostgreSQL DBA y Developer.
Especializado en formar y enseñar a programar.
CEO de Abatic y Cudacu

Reader Interactions

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

He leído y acepto la política de privacidad

Responsable: ABATIC SOLUCIONES TECNOLOGICAS SLU
Finalidad: gestionar los comentarios.
Legitimación: tu consentimiento.
Destinatarios: los datos que me facilitas estarán ubicados en los servidores de Nicalia dentro de la UE. Ver política de privacidad de Nicalia.
Derechos: podrás ejercer tus derechos, entre otros, a acceder, rectificar, limitar, suprimir, portabilidad y olvido de tus datos.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.