Tengamos un ejemplo simplificado siguiente:Sobrecarga de C# con genéricos: ¿error o característica?
void Foo<T>(IEnumerable<T> collection, params T[] items)
{
// ...
}
void Foo<C, T>(C collection, T item)
where C : ICollection<T>
{
// ...
}
void Main()
{
Foo((IEnumerable<int>)new[] { 1 }, 2);
}
compilador dice:
El tipo 'System.Collections.Generic.IEnumerable' no se puede usar como parámetro de tipo 'C' en el tipo genérico o método 'UserQuery.Foo (C, T)'. No hay conversión de referencia implícita de 'System.Collections.Generic.IEnumerable' a 'System.Collections.Generic.ICollection'.
Si cambio a Main
:
void Main()
{
Foo<int>((IEnumerable<int>)new[] { 1 }, 2);
}
Se trabajará bien. ¿Por qué el compilador no elige la sobrecarga derecha?
realmente no hay ninguna conversión entre IEnumerable e ICollection. – nothrow
@Yossarian: dos cosas. Primero, hay una conversión explícita. Quiere decir "realmente no hay una conversión de referencia implícita". En segundo lugar, la pregunta no es "¿por qué estoy obteniendo un error de 'conversión implícita'?" En segundo lugar, la pregunta es "¿por qué el algoritmo de resolución de sobrecarga elige un candidato de coincidencia exacta que no es válido en lugar de elegir el candidato válido pero peor que no coincide exactamente?" –