C# 3.0. Nuevas características II

Introducción

matrix_ico.jpg En la entrada anterior comenzamos a ver las características de c# 3.0, concretamente la inclusión de los inicializadores de objeto y las propiedaes automáticas, que, como vimos, nos permitían mostrar nuestro código de una forma mucho más limpia.

En esta nueva entrega vamos a ver los metodos de extensión que al igual que lo anterior nos facilitarán la vida en ciertas tareas e incluso nos permitiran cambiar, en cierto sentido, nuestra forma de programar.

En términos generales los métodos de extensión se limitan a proporcionarnos la capacidad de extender una clase o interfaz ya existente añadiendole nuevos métodos, es decir, complementar esa clase con nueva funcionalidad (cosas que, por ejemplo, hemos tenido que tener en cuenta más tarde), aunque donde realmente consiguen su máxima potencia los métodos de extensión es en los interfaces y clases genéricos, y su mejor ejemplo (que ya veremos más adelante) es LinQ

Que consiguen

Supongamos que tenemos una aplicación en la que deseamos validar que el campo introducido (un string) sea un email

Normalmente utilizaríamos algo como lo siguiente (evidentemente esto es algo muy simplificado, hay ejemplos mejores)

string mail = txtMail.text;

if (IsEmail(mail))
{

}

mientras que usando una extensión obtendremos la posibilidad de hacer esto..

string mail = txtMail.text;

if (mail.IsEmail())
{

}

Como se implementan

No hay nada más fácil que declarar la extensión anterior, lo único que debemos hacer es declarar, como primer parametro de la función el tipo que deseamos extender precedido de la palabra clave this. Más claro en un ejemplo:

public class MiStringExtender
{
  public bool IsMail(this string s)
  {
    // Y aqui validamos el mail, como si fuera una función normal
  }
}

Vamos a ver un ejemplo un poco más interesante que descubrí leyendo CSharpCorner y que es realmente útil

public static void ForEach<T>(this IEnumerable<T> items, Action<T> act)
{
    foreach (T item in items)
        act(item);
}

Que es una función que no tiene mucha miga, se le pasa un descendiente de IEnumerable (notad que es un interfaz genérico) y un objeto de tipo Action (que en realidad es un delegado genérico y ...

  List<string> miLista = new List<string>;
  RellenaList(miLista);  // Véis que aqui tb podría haber una extensión ...
  miList.ForEach(TrimString);

Conclusión y un pequeño avance

La introducción de métodos de extensión nos proporciona una excelente base para proporcionar funcionalidad de una forma muy intuitiva. En general siempre es más "intuitivo" que una clase se transforme a si misma mediante la llamada a un método que el hecho de que otra clase la transforme, es decir, es mucho más intuitivo hacer un string.IsMail() que un StringHelper.IsMail(string).

Pero cuando realmente comienzan a ser poderosas las extensiones es cuando se unen al concepto de métodos anónimos y lambda expressions que veremos en el siguiente post. En el ejemplo anterior (en el foreach) haccía falta definir una función que se llamaba TrimString que se encargaba de recortar los espacios de la cadena... sin embargo, usando lambda expressions podemos definir

  // Metodos anónimos (esto es de C# 2.0)
  miList.ForEach(delegate(string s) { s.Trim() });

  // Lambda expressions en C# 3.0
  miList.ForEach(s => s.Trim());

no pretendo que entendáis que hemos hecho, eso lo explicaré en el siguiente artículo pero si que veáis que con eso nos ahorramos código y que, una vez sabes lo que significan, son mucho más claras a simpre vista.

5.23913
Average: 5.2 (46 votes)
Your rating: None