De que se trata o artigo

O artigo demonstra como utilizar o recurso de Extension Methods (métodos de extensão) do C# e do Framework .NET, principalmente procurando demonstrar situações práticas, casos que precisam ser considerados e eventuais armadilhas que precisam ser evitadas.

Para que serve

Extension Methods permitem que se estenda a funcionalidade de classes que não podem ser modificadas usando métodos static que se comportam como métodos de instância. De uma maneira mais simples: Extension Methods são escritos em classes separadas, mas, podem ser usados como métodos de instância de classes existentes.

Em que situação o tema é útil

Em conversões de dados que é o cenário mais comum. Em validações de informações digitas por usuário em formulários e também para deixar o código escrito mais direto já que os Extension Methods podem ser usados como se fizesse parte da classe que está sendo usada.

Extension Methods

Nem sempre uma classe vai permitir que seus elementos sejam estendidos através de sobreposição (override) de métodos, ou mesmo que esta seja derivada para acrescentar novas funcionalidades. Neste cenário só resta criar outras classes que usam o objeto que se está manipulando como parâmetros para os seus métodos – o que geralmente implica em um código mais extenso – ou, uma alternativa do Framework .NET chamada Extension Methods.Através destes, pode se usar métodos de classes static como se fizessem parte de um tipo que se deseja manipular (desde os tipos básicos como string até classes mais complexas). Primeiramente vamos rever alguns conceitos da programação orientada a objetos para poder explorar este conceito. Na segunda parte do artigo elaborei uma aplicação demonstrando boa parte do que foi conceituado.

Para compreender o funcionamento dos Extension Methods é importante conhecer o funcionamento das classes em C# e no Framework .NET. Demonstrando de maneira simplificada, considere os tipos de classe quanto à permissão de herança:

  • Classes normais – são aquelas onde é possível criar outra classe derivada;
  • Classes abstratas – precisam ter seus elementos implementados antes de ser usada. Para isto é necessário criar classes derivadas desta. Uma classe deste tipo é identificada com a keyword “abstract” na sua declaração;
  • Classes fechadas – usadas para evitar que sejam herdadas para outras classes. São criadas com a keyword “sealed” colocada na declaração da classe;

Um exemplo de classe abstrata está descrito na Listagem 1.

Listagem 1. Exemplo de classe abstrata


  public abstract class Tributo
  {
      public decimal Calcular(decimal ValorBase, decimal Aliquota);
  }

A classe precisa ser implementada como a Listagem 2 demonstra.

Listagem 2. Implementando uma classe abstrata


public class Icms : Tributo
  {
      public decimal Calcular(decimal ValorBase, decimal Aliquota)
      {
          return ValorBase * Aliquota / 100;
      }
  }

O modificador abstract pode também ser usado com outros elementos da classe como propriedades e métodos. Assim, podemos ter elementos em uma classe que ainda não tenham sido implementados junto com outros já definidos.

Overriding de métodos

Um detalhe importante na definição de classes é que para que um método possa ser sobrescrito, este precisa levar a keyword “virtual” em sua declaração. Uma classe pode ter alguns métodos que sejam fechados para modificação e outros que possam ser sobrescritos. A Listagem 3 demonstra como isto pode ser feito.

Listagem 3. Usando a keyword “virtual”


  public class classeComAlgumaFinalidade
  {
      public int Propriedade1 { get; set; }
      public string Propriedade2 { get; set; }
   
      public void MetodoQueNaoPodeSerSobrescrito()
      {
          // faz alguma coisa
      }
   
      public virtual void MetodoQuePodeSerSobrescrito()
      {
          // faz alguma coisa diferente
      }
  }

No exemplo, o segundo método poderá ser sobrescrito em uma classe que fizer herança da mesma. Para fazer isto a sintaxe usada é como no exemplo abaixo da Listagem 4.

Listagem 4. Fazendo sobreposição de métodos


  public class classeHerdada : classeComAlgumaFinalidade
  {
      public override void MetodoQuePodeSerSobrescrito()
      {
          // faz outra coisa diferente da base
      }
  }

Classes “Static”

Classes deste tipo não requerem uma instância. Normalmente são usadas apenas para implementar funcionalidades como manipular arquivos. Um bom exemplo é a classe System.IO.File. Esta provê métodos para copiar, excluir, renomear e fazer manipulação de arquivos sem precisar criar uma instância. Por exemplo, para verificar se um arquivo existe basta invocar o método diretamente:


  if(File.Exists(“arquivo.txt”))
  {
         // faz alguma coisa
  }

O detalhe importante neste tipo de classe é que não se destinam a armazenamento de dados, uma vez que estes permanecem imutáveis na memória, mas apenas para prover funcionalidades dentro da aplicação.

Extension Methods

Classes static são usadas para implementar uma característica das linguagens procedurais como funções (functions) e procedures no Framework .NET. O inconveniente é que você sempre precisa passar para o método o objeto que esteja sendo manipulado. Considere, por exemplo, uma tarefa comum como a conversão de dados. Se quiser converter uma string para decimal, por exemplo, a sintaxe é a seguinte:

decimal numero = Decimal.Parse(“100”);

O método “Parse” é comum a vários tipos do Framework .NET bem como os métodos da classe “System.Convert” são exemplos de métodos static. A partir da versão 3.0 do Framework .NET implementou um recurso que permite que se definam classes e métodos especiais conhecidos como Extension Methods para que estes se “incorporem” aos tipos existentes e se use estes como se fossem parte da classe incorporada.

Para definir estes, a classe e o método precisam levar a keyword static. O tipo que se deseja incorporar o Extension Method deve ser passado como parâmetro para o mesmo com a keyword “this”. A ...

Quer ler esse conteúdo completo? Tenha acesso completo