Archive for the 'C#' Category

Métodos de Extensão em C# e Java (?)

Métodos de extensão (Extension Methods) são utilizados em situações onde é necessário adicionar mais funcionalidades para uma classe. Em linguagens como Java, o programador é ainda é incapaz de mudar o comportamento de uma classe diretamente. Para fazer isso, ele teria as opções:

  • Herdar a classe e adicionar funcionalidade;
  • Fazer uma classe nova separada, e adicionar um método estático que pega um objeto do tipo da classe e retorna um novo objeto com a modificação desejada.

A primeira opção possui algumas limitações por desfrutar de herança e a segunda é menos intuitiva e requer uma referência para uma classe separada. :(

Bom, pense em uma situação onde se tenha a necessidade de extender a classe String de Java a fim de adicionar um novo método reverse que retorna o valor da string com os caracteres em ordem invertida. Comumente, este método poderia adicionado em uma classe utilitária. Observe o exemplo de implementação:

String x = "some string value"; 
String y = Utility.reverse(x);

Entretanto, é difícil de navegar em classes utilitárias e além disso, diferente dos métodos de String, isto não é um membro da classes String, é uma classe totalmente diferente. Uma melhor sintaxe pra isto seria:

String x = "some string value";
String y = x.reverse();

A boa notícia para programadores C# é que uma das novas features da linguagem (especificação 3.0) é o método de extensão. Programadores Java terão que esperar um pouquinho (?) mais. Pra implementar a abordagem do exemplo anterior, em C#, teríamos:

public static class Util
{
  public static string Reverse(this string input)
  {
    char[] chars = input.ToCharArray();
    Array.Reverse(chars);
    return new String(chars);
  }
}

A grande diferença entre os métodos de extensão e os métodos estáticos normais é que os métodos estáticos são chamados em notação pré-fixa, enquanto que os métodos de extensão são chamados em notação infixa. Exemplo:

  • Métodos de Extensão: x.doSomething1(arg1).doSomething2(arg2)
  • Métodos estáticos: X.doSomething2(X.doSomething1(x, arg1), arg2)

Um método de extensão é uma forma de se alcançar algo como as classes abertas do Ruby. Seria um recurso interessante e facilitaria um tanto a adoção de novidades como closures e outras alterações propostas para Java 7. :)

Uma notícia esperançosa para programadores Java é que segundo Neal Gafter (um dos principais idealizadores de closures) em seu post Closures Prototype Update and Extension Methods mencionou que os métodos de extensão são uma alteração proposta em Java 7 :D ! Olha o pequeno exemplo que ele deu de como a sintaxe vai funcionar:

import static java.util.Collections.sort;
...
List<String> list = ...;
list.sort();

Realmente é uma boa notícia, só temos que aguardar pra ver se vai dar certo mesmo. ;)