martes, 8 de julio de 2014

Métodos de Extensión - Extensions Methods




Los métodos de extensión, nos ofrecen la posibilidad de poder extender las clases de terceros, de poder añadir métodos a clases de las que no disponemos del código fuente y nos es de utilidad añadirles nuevas funcionalidades.


Esta característica se añadió en la versión 3.0 del .Net Framework, y es masivamente utilizada dentro de las librerías de LinQ, especialmente para el tipo IEnumerable<T>, que veremos con posterioridad en la siguiente entrada.






Recuerda que aquí tienes el indice de todos los posts del Curso de LinQ.



Realizar un método de extensión es una tarea muy sencilla, para ello simplemente tendremos que tener una clase pública estática, con un método público estático, y que el primer parámetro de este método vaya precedido por la palabra reservada this, eso significará cual es el tipo que extiende. Vamos a verlo con más detalle.

En el siguiente ejemplo vamos a hacer un método extensor para la clase String haciendo un método que transforme una cadena en la misma cadena pero alternando letras en mayúsculas y minúsculas:


Ejemplo de resultado del método à EjEmPlO dE rEsUlTaDo DeL mÉtOdO


Lo primero que tenemos que tenemos que tener claro es el tipo que vamos a extender, en nuestro ejemplo el tipo String. Antes de empezar vamos a comprobar que el no tenemos disponible para esta clase el método que vamos a crear, que en nuestro ejemplo lo pendremos el nombre de ToMayusMinus:


















Como podemos observar el intellisense, no nos permite utilizar este método, porque todavía no existe.


Crearemos una clase estática para nuestros métodos de extensión:




public static class Extensions
{
 
}


Como podemos ver, de arranque simplemente es una clase pública estática.


Nota: Dentro de nuestro proyectos podemos tener el nº de clases para métodos de extensión que queramos, podríamos tener StringExtension, DateTimeExtensions, MisExtensionesQueridas, etc., tantas como queramos y con el nombre que queramos.




public static class Extensions
{
 
 
    public static string ToMayusMinus(this string llamador)
    {
        string resultado = string.Empty;
 
        var nuevoLlamador = llamador.ToCharArray();
 
 
        for (int i = 0; i < nuevoLlamador.Length; i++)
            if (i%2 == 0)
                nuevoLlamador[i] = Convert.ToChar(nuevoLlamador[i].ToString().ToUpper());
            else
                nuevoLlamador[i] = Convert.ToChar(nuevoLlamador[i].ToString().ToLower());
 
        return  new string(nuevoLlamador);
    }
 
 
 
}


Este sería el cuerpo del método, supongo que muchos puristas dirían que sería más óptimo, manejando los códigos Ascii de los char y demás, pero bueno es solo un ejemplo didáctico. Para nosotros lo importante es fijarnos en que nuestro método es público, estático y que el primer parámetro va precedido por la palabra reservada this, y que indica cual es el tipo que extenderá.


Como veremos ahora en el momento de la utilización del método extensor, no nos será necesario añadir ningún parámetro, ya que este lo inferirá del tipo que realiza la llamada. Vamos a comprobar como ahora ya lo tenemos disponible:


















El compilador tomará el valor para la variable llamador, en nuestro ejemplo de la variable ‘s’, por la inferencia de tipos.


Vamos a ver un gráfico con la definición y el uso que deja todo esto un poco más claro, ya sabéis una imagen vale más que mil palabras:


















Bueno pues ejecutamos y comprobamos que funciona correctamente:


static void Main(string[] args)
{
    string s = "HOLa mI NOMBRE ES PAKKKO";
 
    Console.WriteLine(s.ToMayusMinus());
 
    Console.Read();
}