Pergunta

Eu notei um comportamento estranho com resolução de sobrecarga.

Suponha que eu tenho o seguinte método:

public static void DoSomething<T>(IEnumerable<T> items)
{
    // Whatever

    // For debugging
    Console.WriteLine("DoSomething<T>(IEnumerable<T> items)");
}

Agora, eu sei que este método, muitas vezes, ser chamado com um pequeno número de argumentos explícitos, então por conveniência eu adicionar essa sobrecarga:

public static void DoSomething<T>(params T[] items)
{
    // Whatever

    // For debugging
    Console.WriteLine("DoSomething<T>(params T[] items)");
}

Agora eu tento chamar esses métodos:

var items = new List<string> { "foo", "bar" };
DoSomething(items);
DoSomething("foo", "bar");

Mas em ambos os casos, a sobrecarga com params é chamado. Eu teria esperado que a sobrecarga IEnumerable<T> a ser chamado em caso de um List<T>, porque parece um jogo melhor (pelo menos para mim).

É este o comportamento normal? Alguém poderia explicar isso? Eu não consegui encontrar nenhuma informação clara sobre isso na documentação do MSDN ... Quais são as regras de resolução de sobrecarga envolvidos aqui?

Foi útil?

Solução

Secção 7.4.3 do C especificação # 3.0 é o pouco relevante aqui. Basicamente, a matriz de parâmetro é expandido, para que você está comparando:

public static void DoSomething<T>(T item)

e

public static void DoSomething<T>(IEnumerable<T> item)

O T para o primeiro jogo é inferida a ser List<string> eo T para o segundo jogo é inferida a ser string.

Agora, considere as conversões envolvidos para o argumento de tipo de parâmetro - no primeiro que de List<string> para List<string>; no segundo é List<string> para IEnumerable<string>. A primeira conversão é um melhor que o segundo pelas regras em 7.4.3.4.

O pouco contra-intuitivo é o tipo de inferência. Se você levar isso para fora da equação, ele vai funcionar como você espera que ele:

var items = new List<string> { "foo", "bar" };
DoSomething<string>(items);
DoSomething<string>("foo", "bar");

Nesse ponto, há apenas um membro da função aplicável em cada chamada.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top