O código da questão do último post deve ter deixado muita gente de cabelo em pé, e por isso agradeço a todas as contribuições (feitas via Twitter, comentário, ou e-mail). A pergunta era:

Dado o seguinte código:

static int Funcao(int z) { return 1; }

static void Main()
{
   dynamic x = 3;
   DateTime y = Funcao(x);
}

O que deve acontecer?

  1. Não compila: tenho um erro em tempo de compilação na linha 6;
  2. Compila e em tempo de execução o inteiro é convertido para uma data usando uma conversão implícita no DLR;
  3. Compila e o inteiro é convertido para uma data usando uma conversão explícita do CLR, mas em tempo de compilação, com IL gerada pelo compilador na chamada da função;
  4. Compila mas tenho um erro em tempo de execução na linha 6, porque não é possível converter um inteiro para uma data.

A resposta correta, nada óbvia, é a quarta. Mas ela só não é óbvia se você não entende ainda como o C# 4 trabalha suas chamadas dinamicas. Vou explicar.

As chamadas dinâmicas se propagam. Quando você passou para o método “Funcao” um argumento dinâmico, toda a chamada passou a ser dinâmica, incluindo o retorno. O que há neste código, na verdade, é uma conversão no retorno de dinâmico para DateTime, porque dinâmico é conversível para qualquer tipo. Só que a conversão é feita em runtime. A “Funcao” sendo chamada parece obviamente ser a que está escrita na linha 1, mas o compilador não tem como saber. Pode ser que houvessem diversos outros métodos com o nome “Funcao” e que um deles retornasse algo que fosse possível converter para uma data. De qualquer forma, ao usar algo dinâmico, você efetivamente abandona qualquer checagem estática de tipos ou de chamadas de métodos em tempo de compilação. Como o argumento x era dinâmico, toda a chamada foi dinâmica.

Depois que entendemos isso fica óbvio. Antes, chega a parecer absurdo.

Giovanni Bassi

Arquiteto e desenvolvedor, agilista, escalador, provocador. É fundador e CSA da Lambda3. Programa porque gosta. Acredita que pessoas autogerenciadas funcionam melhor e por acreditar que heterarquia é mais eficiente que hierarquia. Foi reconhecido Microsoft MVP há mais de dez anos, dos mais de vinte que atua no mercado. Já palestrou sobre .NET, Rust, microsserviços, JavaScript, TypeScript, Ruby, Node.js, Frontend e Backend, Agile, etc, no Brasil, e no exterior. Liderou grupos de usuários em assuntos como arquitetura de software, Docker, e .NET.