Usando tipos anônimos como parâmetro
mai 13
Quando a Microsoft anunciou os tipos anônimos (Anonymous Types) eu fiquei bastante contente, era possível criar tipos rapidamente de uma forma muito fácil. Para quem ainda não conhece essa nova funcionalidade aqui vai o link.
Olhando a sintaxe de construção de um tipo anônimo logo associei aos arrays associativos das linguagens de script, conhecidos como Hash. O C# sempre teve o objeto Hashtable, mas não é flexível comparando com linguagens como Ruby ou Javascript. Só pra exemplificar o que estou dizendo:
No Ruby posso chamar um método passando um hash como parâmetro, sintaxe bastante utilizada no Ruby on Rails, dessa forma:
link_to("Profile", :controller => "profiles", :action => "show")
link_to("Profile", :controller => "profiles", :id => @id)
Nas duas linhas de exemplo os dois últimos itens formam uma Hashtable, no caso do Ruby se chama Hash. Do lado do método também fica fácil de capturar o que foi passado. Com tipos anônimos do C# podemos fazer uma sintaxe bem próxima, que ficaria assim:
LinkTo("Profile", new { Controller = "profiles", Action = "show" });
LinkTo("Profile", new { Controller = "profiles", Id = id });
Mas porque utilizar essa forma de passar parâmetros?
É elegante e limpo em alguns casos. Alguns métodos realizam funções onde é necessário informar MUITOS parâmetros para que se tenha um bom nível de customização da ação que será realizada. E como alguns parâmetros são opcionais acabamos tendo que criar várias sobrecargas para o mesmo método, afim de facilitar a vida de quem vai usar.
No exemplo acima estamos utilizando um método cria um link HTML em um ambiente MVC. Como são muitos parâmetros (texto, controller, action, style, class, id, querystring…) e raramente usaremos todos, utilizamos um tipo anônimo para informar os parâmetros “opcionais”. Assim não precisaremos encher a nossa classe com sobrecargas do método LinkTo.
Outro ganho que temos é na hora de adicionar mais um parâmetro ao método. Adicionamos no tipo anônimo e não precisamos alterar as chamadas na aplicação inteira. Mesmo com refactoring isso as vezes é problemático.
Ok! Agora, como crio meu próprio método?
Para ver como funciona vamos implementar um método que cria links, parecido com o que exemplifiquei antes. Primeiro veremos como fica o método – que vou chamar de “CriaLink” –, depois explico oque ele está fazendo:
Criei um extension method de nome GetPropertyValue na classe Object – para quem não sabe do que se trata extension methods falei sobre isso aqui. Esse método busca o valor da propriedade de qualquer objeto passando apenas seu nome. Isso vai ser muito útil para tratar os tipos anônimos.
Já na implementação do método “CriaLink” primeiramente busco os valores das possíveis propriedades atribuídas ao tipo anônimo passado por parâmetro, que é do tipo Object porque não é possível prever um tipo anônimo. O método GetPropertyValue já se responsabiliza por saber se existe ou não a propriedade, no caso dela não existir o resultado é null.
Depois fica mais simples. Apenas criei uma StringBuilder para concatenar a tag de link que vou criar. Testo se as variáveis provenientes dos parametros possuem valores e concateno o valor relativo a cada propriedade.
Por ultimo mostro como podemos utilizar o método que criamos e o resultado obtido.
Já falei aqui o quanto sou fã da flexibilidade das linguagens de script. O C# tem incorporado algumas funcionalidades dessas linguagens e mesmo assim, ao contrário do que eu imaginava, consegue manter sua característica de ser fortemente tipado. Temos que aproveitar isso e tornar nosso código mais inteligente.
Espero que tenham gostado e qualquer duvida ou sugestão é só entrar em contato ou comentar aqui mesmo. Até mais.