Перегрузка, вывод общего типа и ключевое слово «params» - PullRequest
5 голосов
/ 30 ноября 2009

Я только что заметил странное поведение с разрешением перегрузки.

Предположим, у меня есть следующий метод:

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

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

Теперь я знаю, что этот метод часто вызывается с небольшим количеством явных аргументов, поэтому для удобства я добавлю эту перегрузку:

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

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

Теперь я пытаюсь вызвать эти методы:

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

Но в обоих случаях вызывается перегрузка с params. Я ожидал бы, что перегрузка IEnumerable<T> будет вызвана в случае List<T>, потому что это кажется лучшим соответствием (по крайней мере мне).

Это нормальное поведение? Кто-нибудь может это объяснить? Я не смог найти никакой четкой информации об этом в документах MSDN ... Какие правила разрешения перегрузки используются здесь?

1 Ответ

9 голосов
/ 30 ноября 2009

Раздел 7.4.3 спецификации C # 3.0 является здесь соответствующим битом. В основном массив параметров расширен, поэтому вы сравниваете:

public static void DoSomething<T>(T item)

и

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

T для первого матча выводится как List<string>, а T для второго матча выводится как string.

Теперь рассмотрим преобразования для аргумента в тип параметра - в первом это List<string> в List<string>; во втором это List<string> до IEnumerable<string>. Первое преобразование лучше второго по правилам 7.4.3.4.

Противоинтуитивный бит - это вывод типа. Если вы возьмете это из уравнения, оно будет работать так, как вы ожидаете:

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

В этот момент в каждом вызове есть только один подходящий элемент функции.

...