C#, перегружающийся с дженериками: ошибка или функция?

Давайте иметь следующий упрощенный пример:

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);
}

В компиляторе говорится:

Тип 'Система. Наборы. Универсальный. IEnumerable' не может использоваться в качестве параметра типа 'C' в универсальном типе или методе 'UserQuery. Нечто (C, T)'. Нет никакого неявного ссылочного преобразования из 'Системы. Наборы. Универсальный. IEnumerable' к 'Системе. Наборы. Универсальный. ICollection'.

Если я изменяюсь Main кому:

void Main()
{
    Foo<int>((IEnumerable<int>)new[] { 1 }, 2);
}

Это будет работать хорошо. Почему компилятор не выбирает правильную перегрузку?

8
задан TN. 6 April 2010 в 18:08
поделиться

2 ответа

Здесь дан ответ на ваш вопрос.

http://blogs.msdn.com/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx

Пожалуйста, также прочтите примерно миллион комментариев, в которых говорится Мне кажется, что я ошибаюсь в некоторых интересных дополнительных комментариях по этому вопросу.

15
ответ дан 5 December 2019 в 10:02
поделиться

Я предполагаю, что компилятор выбирает наилучшее соответствие, прежде чем использовать общее ограничение. В вашем примере предпочтительнее использовать метод с ограничением, поскольку он не имеет последнего параметра params .

Править - Эрик Липперт подтверждает это в своем ответе.

2
ответ дан 5 December 2019 в 10:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: