La versión 2.0 de la plataforma .NET permite crear métodos y clases genéricas que trabajen de la misma manera, independientemente del tipo que utilicen para la operación. Puedes leer la introducción al tema que escribí hace ya un par de años (¡como pasa el tiempo!) con las primeras betas de .NET 2.0 en mi post: "Tipos Genéricos en .NET 2.0".

El otro día me preguntaron cómo se podía hacer una función que sirviera para transformar de forma genérica entre dos tipos de datos. Es decir, una a la que le pasases una variable de un valor o una referencia de un determinado tipo y que devolviera el mismo valor pero con un tipo de dato diferente.

En realidad ya existe una función similar desde la primera versión de .NET, y es el método ChangeType de la clase Convert. Este método tiene varias sobrecargas pero la que se usa más habitualmente toma como primer parámetro un valor a convertir y como segundo una definición de tipo al que deseamos convertir el anterior. Así, por ejemplo, para cambiar desde un double a un entero, escribiríamos algo así:

double d = 12;
int i = (int) Convert.ChangeType(d, typeof(int));

Esto está bien para hacerlo de forma genérica pero es bastante lioso. Para empezar el método devuelve un objeto que hay que convertir en su tipo adecuado subyacente, lo que a fin de cuentas nos resta genericidad pues ¿cómo encapsulas en un método lo anteiror?. Además la sintaxis es liosa y difícil de leer.

¿no sería mejor disponer de un método más sencillo y directo de conseguir lo mismo?

Es aquí donde entran los genéricos. Pensé en utilizar un método que use genericidad para conseguir el mismo efecto pero que sea sencillo de utilizar desde código y funcione de un modo realmente general. El resultado es este código:

public static T Convertir<T>(object v)
{
   try
   {
      return (T) Convert.ChangeType(v, typeof(T));
   }
   catch
   {
      return (T) Activator.CreateInstance(typeof(T));
   }
}

Con él la conversión entre dos tipos cualquiera es tan fácil como en este ejemplo:

DateTime d = DateTime.Now;
string s = Convertir<string>(d);

la sintaxis es mucho más clara y directa ¿no?

Realmente lo único que hace es encapsular el uso del método ChangeType permitiendo su uso de forma genérica y facilitando el uso general desde el código.

Este método además tiene la particularidad de que siempre devuelve un valor del tipo adecuado ya que si la conversión falla instancia un objeto nuevo de ese tipo. Esto último no tiene porque ser interesante siempre así que es fácil sustituirlo por el lanzamiento de una excepción de tipo InvalidCastException cuando la conversión no sea posible.

💪🏻 ¿Este post te ha ayudado?, ¿has aprendido algo nuevo?
Pues NO te pido que me invites a un café... Te pido algo más fácil y mucho mejor