Respondendo então à questão de qual overload é utilizado que fiz aqui na quinta-feira passada. Se você não viu a questão, leia lá antes de ler aqui para não perder a graça.

Revendo as funções:

FazAlgo(object arg) {} //overload 1
FazAlgo(params object[] args) {} //overload 2

Minha chamada é assim:

string[] parametros = {"Giovanni", "Bassi"};
FazAlgo(parametros);

Qual overload é chamado? Revendo as opções:

  1. O primeiro é chamado, passando um array de strings como um objeto.
  2. O segundo é chamado, passando um array de strings como se fosse um array de objetos.
  3. O segundo é chamado, passando um array de strings como um objeto do array args, como se implicitamente fizesse “FazAlgo(new object[] {parametros})”

Adianto que a opção 3, apesar de tecnicamente ser possível, não é a correta porque há duas opções mais diretas. Nesta terceira opção o compilador tem que expandir o objeto de object para object[], e, como nas outras duas opção não há mudança alguma, a terceira opção é descartada.

Graças à covariância entre arrays, podemos converter implicitamente de string[] para object[]. Isso coloca o overload 2 como mais específico que o overload 1, e portanto ele é o escolhido. Um array de strings pode até ser um object, mas ele é mais especificamente um array de objetos. O tipo mais específico sempre ganha.

Engraçado que normalmente quando essa questão é levantada a maioria das pessoas dizem que a opção 1 é a correta. Mas não me parece a mais óbvia. Talvez as pessoas não entendam a questão da variância.

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.