Как говорит Эрик Липперт :
Спецификация C # говорит, что когда у вас есть выбор между вызовами ReallyDoIt<string>(string)
и ReallyDoIt(string)
- то есть когда выбормежду двумя методами, которые имеют идентичные сигнатуры, но один получает эту сигнатуру посредством универсальной замены - тогда мы выбираем «естественную» сигнатуру вместо «замещенной» сигнатуры.
ОБНОВЛЕНИЕ:
Чтомы имеем в C # spec (7.5.3):
Когда универсальный метод вызывается без указания аргументов типа, процесс вывода типа пытается определить аргументы типа для вызова.Посредством вывода типа аргумент типа int определяется из аргумента метода.Вывод типа происходит как часть обработки времени привязки вызова метода и выполняет before
шаг разрешения перегрузки вызова.
Если в вызове метода указана конкретная группа методов, а в качестве части вызова метода не указаны аргументы типа, вывод типа применяется к каждому универсальному методу в группе методов.Если вывод типа завершается успешно, выводимые аргументы типа используются для определения типов аргументов для последующего разрешения перегрузки.Если при разрешении перегрузки выбирается универсальный метод для вызова, то в качестве фактических аргументов типа для вызова используются аргументы предполагаемого типа.Если вывод типа для определенного метода завершается неудачей, этот метод не участвует в разрешении перегрузки.
Итак, перед разрешением перегрузки у нас есть два метода в группе методов.Один DoWork(int)
и другой вывод DoWork<int>(int)
.
И мы переходим к 7.5.3.2 (лучший элемент функции):
В случае последовательности типа параметра {P1, P2,…, PN} и {Q1, Q2,…, QN} эквивалентны (т. е. каждый Pi имеет преобразование идентичности в соответствующий Qi), для определения лучшего члена функции применяются следующие правила разрыва связи. 1) Если MP - неуниверсальный метод, а MQ - универсальный метод, то MP лучше, чем MQ.