Desenvolvimento - C#

Extensions Methods

Os Extension Methods permitem que o desenvolvedor adicione métodos a um determinado tipo sem a necessidade de alterar o código fonte original ou criar tipos derivados. Os métodos que são adicionados têm as mesmas características de um método estático, porém, a utilização dos mesmos funciona como se eles fossem métodos de instância. Esse recurso foi largamente utilizado para disponibilizar os métodos que trabalham com LINQ na versão mais recente do framework .net.

por Denis Ferrari



Tecnologias

  • Framework 3.5
  • C# 3.0

MSDN

Introdução

Olá pessoal, hoje vou falar um pouco sobre essa novidade do C# 3.0 que são os Extension Methods. Minha motivação para escrever esse artigo foi uma discussão que tive com alguns colegas de trabalho sobre a padronização da utilização desse recurso e quando utilizar ou não o mesmo.

Os Extension Methods permitem que o desenvolvedor adicione métodos a um determinado tipo sem a necessidade de alterar o código fonte original ou criar tipos derivados. Os métodos que são adicionados têm as mesmas características de um método estático, porém, a utilização dos mesmos funciona como se eles fossem métodos de instância. Esse recurso foi largamente utilizado para disponibilizar os métodos que trabalham com LINQ na versão mais recente do framework .net.

Definição

A definição é relativamente simples, para criar um extension method siga os seguintes passos:

  1. Crie um arquivo de código.
  2. Defina uma classe estática.
  3. A classe deve estar em um namespace acessível para os clientes.
  4. Defina um método estático com o primeiro argumento sendo do tipo que você pretende estender, antes do tipo adicione a palavra “this”.
  5. Escreva o corpo do método.

Ao final, você terá algo semelhante à imagem 01:

String.ToInt32.jpg
Imagem 01

Como podem ver na linha 1, defini que minha classe ficaria no namespace System, fiz isso por que a classe String também está nesse namespace, logo, quem estiver usando a classe também terá acesso ao método ToInt32.

Na linha 3 defini a classe StringExtensions como sendo pública e estática. Você pode usar o nome que quiser para a classe.

Dica
Eu adotei um padrão onde o nome da classe estática fica sendo sempre o tipo que estou estendendo seguido da palavra Extensions.

Na linha 5 declarei o método estático ToInt32, vocês podem reparar que a grande diferença aqui é a utilização da palavra this antes do primeiro parâmetro do método. O método tem que ter no mínimo um parâmetro sendo do tipo que você pretende estender.

Vejam como ficou a utilização do método na imagem 02:

Program_1.jpg
Imagem 02

Como vimos, a utilização do método fica bem prática, como se o mesmo fosse de instância, e não estático.

Quando utilizar?

Apesar de ser um método estático, o mesmo será utilizado como um método de instância, logo, o ideal é utilizar esse recurso quando faça sentido que o método seja utilizado assim.

Vale a pena utilizar esse recurso, pois a sintaxe fica bem mais limpa do que um método utilitário normal.

Program_2.jpg
Imagem 03

A imagem 03 possibilita a comparação entre a utilização convencional, e da utilização do extension method.

Dica
Métodos auxiliares nem sempre são bons candidatos a serem extension methods, exemplos de métodos que não deveriam utilizar esse recurso: FormatarCpf(), FormatarCnpj(), EhEmailValido(). Nesses casos, continue utilizando os métodos estáticos convencionais no padrão de assistente.

Organização dos arquivos

A organização dos arquivos é um ponto crucial para trabalhar em projetos com vários desenvolvedores. Quando usamos extensions podemos confundir o time de desenvolvimento já que os métodos não ficam junto com a definição do tipo, logo, use um padrão que fique bem explícito que o projeto usa esse recurso.

Arquivos.jpg
Imagem 04

A imagem o4 mostra como organizei os arquivos do projeto de exemplo, notem que existe uma pasta específica para Extensions, onde ficam os métodos para tipos do sistema, como string, int, etc. No caso da interface IPessoa, seus métodos ficam em um arquivo de mesmo nome com sufixo “.sufixo”.

Dica
Defina o padrão que atende melhor as necessidades do projeto e da equipe de desenvolvimento, a regra não é usar o padrão que estou usando, mais sim usar um padrão que todos os envolvidos no projeto entendam.

Mixin

Um efeito colateral bom da inserção dos extension methods é o fato do desenvolvedor poder adicionar comportamentos a interfaces, esses comportamentos por sua vez poderão ser utilizados em todos os tipos que implementam a interface. As próximas imagens ilustram o cenário:

Mixin_1.jpg
Imagem 05

Mixin_2.jpg
Imagem 06

Mixin_3.jpg
Imagem 07

Como podem ver, declarei uma interface IPessoa e duas classes que implementam a mesma. Adicionei um Extension Method à interface IPessoa e depois pude utilizar o método nos tipos que implementam a interface.

Veja mais sobre mixin.

Conclusão

Nesse artigo mostrei como utilizar os Extension Methods e quais são as melhores práticas envolvidas com o recurso. Espero que tenham gostado, e aguardo feedbacks.

Abraços,
Denis Ferrari

Download do projeto de exemplo.

Denis Ferrari

Denis Ferrari - Atua como desenvolvedor de aplicações para empresas capixabas a cerca de cinco anos. Graduando em sistemas de informação pela FAESA. Fornece treinamentos na plataforma .net e publica artigos que podem ser encontrados no site http://desenvolvimento.denisferrari.com. Possui as credenciais de MCP, MCTS (Web) e MCPD (Web).