Estendendo sem herança (Extension Methods) em C#

Sabemos que usar herança para reaproveitar código não é a melhor solução. Sendo assim, existe algum recurso do C# que nos permita reaproveitar código sem ter que usar herança? Sim existe, e seu nome é Extension Methods.

Extension Methods é o recurso do C# que lhe permite “adicionar” métodos a uma classe já existente sem ter que estendê-la (por herança), recompilá-la ou alterá-la e pode ser definido como um tipo especial de método estático. Entretanto, o código cliente de um método de extensão o acessa como se este fosse um método não-estático. Em outras palavras, o método de extensão apesar de ser estático, é acessado pela referência. Tecnicamente falando, ou seja, por debaixo dos panos não é bem assim que acontece, mas isso é uma discussão mais aprofundada. O importante aqui é como o desenvolvedor escreve a chamada.

A própria API do .NET faz um uso interessante de Extension Methods para estender as classes que implementam a interface IEnumerable. Esses métodos são conhecidos como operadores padrão LINQ. Alguns deles: Count(), Distinct(), ElementAt(), First(), FirstOrDefault(), GroupBy(), OfType(), Sum(), ToList() e muitos outros. Para destacar os extension methods, a IDE do Visual Studio utiliza o ícone de chamada de método com uma seta azul direcionada para baixo, conforme mostra a figura abaixo.

E então, como faço para criar meus próprios Extension Methods ?

É simples. Basta criar um método com a palavra reservada this antes do tipo do primeiro argumento. Este deverá ser do tipo que será estendido. Lembrando que tanto o método quanto a classe devem ser estáticos.

Exemplo: criar uma extensão para classe String que dada um texto, retorne o próprio sem os espaços em branco.

E como faço para usar minha nova extensão? Praticamente nada! Agora toda referência à classe String poderá invocar o método RemoverEspaços. Única coisa que precisa ser lembrada é que é necessário fazer o using no namespace onde a classe de extensão foi declarada, como mostra o exemplo de uso abaixo:

Repare que na chamada ao método não necessário passar o parâmetro texto! E se eu precisar passar algum parâmetro? Sem problemas, a única exigência é que a referência ao tipo que está sendo estendido seja o primeiro argumento do método.

Exemplo: criar um método de extensão para classe String para replicar um texto N vezes.

Uso:

Além evitar o uso desnecessário da herança, uma outra notável utilidade dos métodos de extensão é a possibilidade de estender uma classe que foi definida em um código fonte que não se tem acesso. Por exemplo, se você adiciona alguma biblioteca de código fechado ao seu projeto, e esta é muito difícil de usar, você pode usar métodos de extensão para tornar o uso mais fácil. Bem, isso é o básico sobre métodos de extensão. Existem alguns problemas e efeitos colaterais do mal uso desse recurso que será abordado no próximo post. Aguardem.

Até a próxima.

About Luciano Castilhos

Desenvolvedor @ Modulo Solutions for GRC

4 Responses to “Estendendo sem herança (Extension Methods) em C#”

  1. Marlon Gaspar says :

    Bacana, Luciano!

    Olha, eu confesso que não morro de amores pelos métodos de extensão, mas tem um cenário que eles são matadores: criar métodos para interfaces! Além de permitir a definição dos métodos fora de um namespace ou ou assembly de “contrato” (esse é uma perda da opção mais usada, as classes abstratas), pode-se aplicar a interface a várias classes e assim habilitar um cenário de “herança múltipla”, que o pessoal chama de mixin.

    Abraços!

    • Luciano Castilhos says :

      Eu acho um bom quebra-galho, mas sempre tenho um pé atrás porque existe sempre uma tendência da comunidade a querer usar um recurso interessante como solução para tudo. De qualquer forma, eu gosto muito de criar extensões para resolver problemas corriqueiros com as classes mais usadas no dia-a-dia como Dictionary, String, etc. Estava até querendo startar um projeto open-source para colocar esses métodos, eles estão espalhados em vários projetos meus. Agora um uso muito interessante que tive de Extension Method foi para estender uma biblioteca de conexão SSH. Transformei os comandos Unix (ls, cat, etc) em métodos de extensão, foi bem útil.

  2. Raphael Lacerda says :

    Excelente post…não vejo a hora de utilizá-los no Java 8

  3. Marco Malvessi says :

    Excelente post!
    Muito bem explicado e organizado.
    Parabéns Luciano!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>