Extension Methods em C#

Um conceito muito interessante e novo no C# 3.0 e que tem aparecido bastante em blogs ultimamente é o conceito de métodos de extensão. Penso que já todhttp://miguelalho.com/wp-admin/post.php?action=edit&post=867&message=1&_wp_original_http_referer=http%3A%2F%2Fmiguelalho.com%2F%3Fp%3D867os nós tivemos que escrever um ou outro conjunto de métodos estáticos auxiliares para manipular objectos, normalmente agrupados em classes com o nome de “Helper”. Métodos de extensão são essencialmente isso mesmo, mas com uma sintaxe mais amigável.

Um exemplo é certamente a melhor forma de explicar.

Supomos um método de manipulação de strings, que não está presente na classe String do .NET, por exemplo, que conte o número de caracteres de espaço na string. Sem métodos de extensão, eu primeiro criava uma classe auxiliar com o método estático para efectuar o passo:

public class StringHelper
{
	public static int GetSpaceCount(string s)
	{
		int output = 0;
		foreach(char c in s)
		{
			if(c==' ')
				output++;
		}
		return output;
	}
}

GetSpaceCount é estático, recebe uma string (a que tem os espaços que queremos contar), e retorna o inteiro com o número de espaços. Para o utilizar, posso fazer o seguinte, por exemplo:

string text = "Olá tudo bem?";
Console.WriteLine(StringHelper.GetSpaceCount(text));

Onde o método é chamado da forma “nome da classe”.”nome do método estático”(“parâmetro”).

O métodos de extensão oferecem uma forma mais elegante e natural de chamar o método, como se pertencesse à classe da instância, ou seja, poderia escrever a mesma linha da seguinte forma:

Console.WriteLine( text.GetSpaceCount());

Repara que text.GetSpaceCount() é bem mais simples, legível e intuitivo que StringHelper.GetSpaceCount(text) . Para criar o método de extensão temos passos semelhantes ao da criação do helper, mas com uns detalhes a ter em conta. Primeiro, a própria classe de suporte é estático. Segundo, o método é também estático. Terceiro, na lista de parâmetros, o primeiro parâmetro é do tipo sobre a qual trabalhamos e deve ser precedido da palavra “this”. Portanto a mesma classe reescrita fica:

public static class StringExtension
{
	public static int GetSpaceCount(this string s)
	{
		int output = 0;
		foreach(char c in s)
		{
			if(c==' ')
				output++;
		}
		return output;
	}
}

É necessário que o projecto tenha a referência ao System.Core.dll. A partir daqui, o método fica disponível para trabalhar directamente sobre strings e com suporte intellisense e tudo.

O conceito é óptimo para construir classes que possam ser reaproveitados em diversos projectos e incluídos num framework, e ajudar a manter um código limpo e legível. Basta depois referir a DLL e/ou namespace que contem os métodos.

Como referencias, seguem alguns links: