Binding dos métodos em tempo de compilação ou execução com C#

Email

A maneira do C# funcionar é muito interessante, além de lógica. Vejam esse caso. Se tenho esta classe:

public class Classe
{
    public static string Estatico(object o)
    {
        return Metodo(o);
    }
    private static string Metodo(string s)
    {
        return "string";
    }
    private static string Metodo(object o)
    {
        return "object";
    }
}

Independente do parâmetro que eu passar para o método “Estático”, ele sempre vai chamar o método “Metodo” com parâmetro object. O que recebe parâmetro string nunca será chamado. Isso acontece porque o binding da chamada acontece em tempo de compilação, e a IL escrita identifica claramente que o método chamado é parâmetro object, já que o com parâmetro string não atende. Ao chamar o método em runtime e passar uma string, a ligação entre o método “Estatico” e “Metodo(object)” já está feita.

Estes testes servem pra confirmar isso:

[TestMethod]
public void EstaticoString()
{
    Assert.AreEqual("object", Classe.Estatico(""));
}
[TestMethod]
public void EstaticoObject()
{
    Assert.AreEqual("object", Classe.Estatico(1));
}

 

Existe alguma maneira de fazer com que o método que recebe uma string seja chamado? Existe. Desde que o C# incorporou características dinâmicas, em sua versão 4, é possível atrasar a resolução do overload escolhido para o tempo de execução, deixando de fazê-la em tempo de compilação. Assim, se quisermos que isso aconteça só quando a aplicação estiver rodando, basta trocar o tipo do parâmetro do método “Estatico” de object pra dynamic. Eu preferi criar outro método:

public static string Dinamico(dynamic d)
{
    return Metodo(d);
}

 

Esse método não sabem qual overload está sendo chamado em tempo de compilação. Isso só é resolvido quando a aplicação está rodando. Nesse momento, é possível perceber que o parâmetro é uma string e chamar o overload apropriado.

Aqui os testes:

[TestMethod]
public void DinamicoString()
{
    Assert.AreEqual("string", Classe.Dinamico(""));
}
[TestMethod]
public void DinamicoObject()
{
    Assert.AreEqual("object", Classe.Dinamico(1));
}

Interessante, não?

Coloquei todo o código no gist. Vejam lá, comentem, forkem, baixem, divirtam-se.

Email
Esse post foi publicado em Engenharia e marcado por Giovanni Bassi. Marcar link permanente.

Sobre Giovanni Bassi

Arquiteto e desenvolvedor, agilista, pai, filho, namorado, escalador, provocador.
Programa porque gosta, e começou a trabalhar com isso porque acha que trabalhar como administrador é meio chato. Por esse motivo sempre diz que nunca mais vai virar gerente de ninguém. E também porque acredita que pessoas autogerenciadas funcionam melhor e por acreditar que heterarquia é melhor que hierarquia. Mas isso é outro assunto.
Foi reconhecido  Microsoft MVP depois que alguém notou que ele não dormia a noite pra ficar escrevendo artigos, cuidando e participando do .Net Architects, gravando o podcast Tecnoretórica, escrevendo posts no blog e falando o que bem entende no twitter @giovannibassi. E por falar nisso é no twitter que conta pra todos que gerencia de projetos deve ser feita pelo time e não por um gerentes, que greves em TI são coisas sem sentido e que stored procedure com regras de negócio são malígnas.
Você já deve ter percebido (até porque está lá na primeira frase) que Giovanni é agilista. De tanto gostar disso ele trouxe os programas de certificação e treinamento  PSD e PSM da Scrum.org pro Brasil, e por causa deles, do MVP e de algum trabalho que aparece tem que ficar indo pros EUA de vez enquando, coisa que prefere não fazer. (É bem comum você ouvir ele perguntando porque a Scrum.org e a Microsoft não estão na Itália, por exemplo.)
Junto com alguns Jedis criou a Lambda3, que, apesar de ser pequena e de não ser muito comum no Brasil, insiste em fazer projetos e consultoria direito. Por causa da Lambda3 ele tem trabalhado mais do que quando era consultor independente, mas menos do que a maioria das pessoas. Quer dizer, isso se você considerar que os trabalhos junto à comunidade não são trabalho, caso contrário ele trabalha mais que a maioria das pessoas.
Recentemente ele resolveu que merecia viver melhor e ganhar uns anos de vida e desistiu de ser sedentário, fazendo algum barulho de vez em quando com os amigos no twitter com a hashtag #DotNetEmForma. Por causa do convite recente de amigos do lado Open Source (que ele respeita e admira), começou a escalar, e agora está sempre com as mãos machucadas. Mas ainda dá pra programar. Você encontra ele sempre em algum evento, como o TechEd, e o DNAD, mas também outros menos comuns para o pessoal do .NET, como a RubyConf. Nesses eventos, ou ele está vendo palestras, ou batendo papo com alguém, ou codando alguma aplicação que alguém achou que dava pra fazer durante o evento.
  • Marcelorocha777

    ou codando alguma aplicação que alguém achou que dava pra fazer durante o evento.Ver todas as mensagens por Giovanni Bassi →

    por favor corrigi está frase

  • http://www.facebook.com/rafaelzaccanini Rafael Zaccanini

    Legal heim….