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:
- O primeiro é chamado, passando um array de strings como um objeto.
- O segundo é chamado, passando um array de strings como se fosse um array de objetos.
- 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.
Postado na(s) categoria(s)
.Net
pelo
giovanni bassi em 8 de junho de 2009 às 10:50
| Tags:
c#
bd65506f-27d8-4341-a2e9-e92c701efbf7|1|5.0