2016-08-31 3 views
3

у меня есть следующие методы:Почему эта перегрузка метода C# не работает должным образом?

public void Say<TItem>(TItem item) 
{ 
    Console.WriteLine("A"); 
} 

public void Say<TItem>(IEnumerable<TItem> items) 
{ 
    Console.WriteLine("B"); 
} 

Когда я бегу следующее:

void Main() 
{ 
    Say<string>("Foo"); 
    Say(new string[] { "Foo", "Bar"}); 

} 

Первый метод вызывается дважды:

A 
A 

Примечание Изменение IEnumerable<T> к TItem[] делает работают как ожидалось, но в случае IEnumerable<T> почему он не поднимает второй метод? Как я могу достичь предполагаемой перегрузки?

ответ

6

Потому что он считает, что TItem is string[]. Посмотрите на это с точки зрения компилятора: все, что он знает, это то, что он ищет общий тип для подключения к этому методу. Так получилось, что строка [] является типом. Поскольку смысл здесь потенциально неоднозначный, вы должны дать компилятору некоторую помощь, чтобы выбрать, какие перегружать вы ищете здесь:

Say<string>(new string[]{"Foo", "Bar"}); 

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

+0

Отлично, но почему эта дополнительная помощь не требуется, если тип параметра является 'string []' в отличие от 'IEnumerable '? – MaYaN

+1

@MaYaN В обоих случаях ваш вызов может потенциально соответствовать обеим подписям. Когда метод принимает «IEnumerable», для сопоставления требуется неявный листинг, где для другого метода не требуется такой отбор. В уме компилятора это делает первую перегрузку более близкой. Когда вы становитесь более конкретными, компилятор может лучше понять, что вы пытались сделать. – pquest

Смежные вопросы