Duck Typing com C# 4.0 e Dynamic Type
O estilo Duck Typing é muito comum para programadores de linguagens dinâmicas, como por exemplo, Ruby. Ele permite que um objeto seja passado para um método que espera um certo tipo, mesmo que o objeto não seja deste tipo. Popularmente, o Duck Typing é definido pela frase a seguir:
If it walks like a duck and quacks like a duck, it must be a duck.
Numa tradução livre, seria algo como: “Se isso anda como um pato e fala como um pato, isso deve ser um pato”. Observe com bastante atenção o código abaixo. Repare que da linha 24 a 27 o método FazerQuack recebe um objeto do tipo dynamic, e usa a propriedade FazQuack() desse objeto. Não importa se o objeto é do tipo Pato ou Humano, desde que ele “faça quack” ele atenderá ao objetivo do método.
Experimente descomentar o código das linhas 18 e 19, e observe que ocorrerá um erro. Isso porque ao utilizarmos o tipo dynamic a checagem será realizada apenas em tempo de execução.
using System;
public class Program
{
static void Main()
{
Executar();
}
private static void Executar()
{
var pato = new Pato();
var homem = new Humano();
FazerQuack(pato);
FazerQuack(homem);
//var cao = new Cachorro();
//FazerQuack(cao); // Essa linha gera um erro.
Console.ReadKey();
}
private static void FazerQuack(dynamic ser)
{
ser.FazQuack();
}
}
internal class Pato
{
public void FazQuack()
{
Console.WriteLine("Quack!");
}
}
internal class Humano
{
public void FazQuack()
{
Console.WriteLine("Eu sei falar 'Quack!'");
}
}
internal class Cachorro
{
public void FazAu()
{
Console.WriteLine("Au!");
}
}
Esse tipo de abordagem nos faz refletir sobre o equilíbrio entre o valor da tipagem forte e a produtividade de trabalharmos em um contexto dinâmico. Com o advento do C# 4.0 e suas bibliotecas dinâmicas, ficou bem mais fácil adotar esse estilo de programação.
Para exemplificar um dos possíveis problemas do Duck Typing, imagine termos métodos com o mesmo nome mas que não desempenham a mesma atividade. Claro que isso dependerá de quem estiver programando, mas o fato é que quando trabalhamos com dinamismo temos muito poder nas mãos, e erros serão mais desastrosos ao código do que dentro de um contexto estático e fortemente tipado.
O código-fonte de exemplo demonstrado pode ser baixado aqui: