may 14, 2013 - .NET    No Comments

Métodos de extensión en .NET

Desde la versión 3.0 del .NET Framework podemos disfrutar de una de las características que más me gusta, hablo de los métodos de extensión que nos dan la posibilidad de agregar métodos a clases que ya están selladas o que no pueden ser heredadas. La mayor parte de esta funcionalidad se utiliza para agregar métodos a las clases de terceros o a las propias del System.

Requisitos

  • Visual Studio 2008+

Manos a la obra

Para utilizar los métodos de extensión debemos en una clase propia declarada como estática definir los nuevos métodos que se agregaran, éstos métodos deben ser declarados como estáticos y la firma debe ser de la siguiente forma:

public static ReturnType MethodName(this InputType ParamName)

Donde ReturnType es el tipo de datos que va a devolver el método y el InputType es el tipo de datos de entrada, que debe ser el mismo tipo de la clase que lo va a utilizar. Por ejemplo:

public static string Invert(this string inputString)
{
	char[] inputStringChars = inputString.ToCharArray();
	Array.Reverse(inputStringChars);
	return new string(inputStringChars);
}

El método Invert estará disponible en la clase string y devolvera un string (de allí que el ReturnType e InputType sean string).
Si probamos nuestro método en una aplicación de consola como esta:

string word;
Console.WriteLine("Escriba una palabra");
word = Console.ReadLine();
Console.WriteLine("String invertida: {0}" ,word.Invert());

Este será el resultado que nos proporciona:

image_thumb.png

Como ven el método Invert() ahora queda disponible en la clase string (Siempre y cuando se haya agregado la diferencia). Con esto en mente imaginen las posibilidades que ofrece esta funcionalidad, por lo menos yo tego mi clase con unos cuantos métodos de muchas utilidad. Les dejo el código:

namespace ExtensionMethods
{
  public static class StringMethods
  {
    /// <summary>
    ///  Invert the string
    /// </summary>
    /// <returns>The string inverted</returns>
    public static string Invert(this string inputString)
    {
      char[] inputStringChars = inputString.ToCharArray();
      Array.Reverse(inputStringChars);
      return new string(inputStringChars);
    }
	/// <summary>
    /// Truncates the string to the specified size adding a string ending
    /// </summary>
    /// <example>
    /// input: Hello world
    /// output: Hello...
    /// </example>
    /// <param name="lenght">Lenght of desired string</param>
    /// <param name="endString">Ending string at the original string</param>
    /// <returns>The truncated string with the ending string</returns>
    public static string Truncate(this string inputString, int lenght, string endString)
    {
      if (inputString == null)
        throw new NullReferenceException();
		if (endString == null)
        throw new NullReferenceException();
		string returnValue = inputString;
      int endStringLenght = endString.Length;
      int inputStringLenght = inputString.Length;
      int totalCharstoCut = inputStringLenght - lenght + endStringLenght;
      if (inputStringLenght > totalCharstoCut)
      {
        returnValue = inputString.Substring(0, inputStringLenght - totalCharstoCut);
        returnValue = returnValue + endString;
      }       return returnValue;
    }

	/// <summary>
    ///  Remove accent from strings
    /// </summary>
    /// <example>
    /// Input: "&aacute;ff&ouml;rd&agrave;&ntilde;&Ccedil;a"
    /// result: "affordanca"
    /// </example>
    /// <remarks>
    ///  From Michael Kaplan blog at http://blogs.msdn.com/b/michkap/archive/2007/05/14/2629747.aspx
    ///  </remarks>
    /// <returns>string without accents</returns>
    public static string RemoveDiacritics(this string s)
    {
      string stFormD = s.Normalize(NormalizationForm.FormD);
      StringBuilder sb = new StringBuilder();
	  for (int ich = 0; ich < stFormD.Length; ich++)
      {
        UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);
        if (uc != UnicodeCategory.NonSpacingMark)
        {
          sb.Append(stFormD[ich]);
        }
      }
      return (sb.ToString().Normalize(NormalizationForm.FormC));
    }

	/// <summary>
    /// Replace \r\n or \n by &#39;br&#39; HTML Tag
    /// </summary>
    /// <remarks>
    /// From Gunnar Peipman blog at http://weblogs.asp.net/gunnarpeipman/archive/2007/11/18/c-extension-methods.aspx
    /// </remarks>
    /// <returns></returns>
    public static string Nl2Br(this string s)
    {
      return s.Replace("\r\n", "").Replace("\n", "");
    }
  }
}

Conclusión

Los métodos de extensión pueden ser una gran ayuda, yo los veo como métodos helpers y en realidad son muy fáciles de implementar. Además pueden también ser utilizados en cualquier tipo de datos, sin necesidad de heredar la clase y acarrear todo lo que esto conlleva.

Happy coding!

Got anything to say? Go ahead and leave a comment!