Как C# выбирает с неопределенностью и параметрами

Скажем, у меня есть следующие методы:

public static void MyCoolMethod(params object[] allObjects)
{
}

public static void MyCoolMethod(object oneAlone, params object[] restOfTheObjects)
{
}

Если я сделаю это:

MyCoolMethod("Hi", "test");

какой из них называют и почему?

3 ответа

Решение

Это легко проверить - вызывается второй метод.

Что касается того, почему - в спецификации языка C# есть несколько довольно подробных правил о том, как разрешаются неоднозначные объявления функций. Есть много вопросов о SO окружающих интерфейсах, наследовании и перегрузках с некоторыми конкретными примерами того, почему вызываются разные перегрузки, но для ответа на этот конкретный случай:

C# спецификация - разрешение перегрузки

7.5.3.2 Лучший функциональный член

В целях определения лучшего члена функции создается урезанный список аргументов A, содержащий только сами выражения аргументов в порядке их появления в исходном списке аргументов.

Списки параметров для каждого из функций-кандидатов строятся следующим образом:

  • Расширенная форма используется, если функция-член была применима только в расширенной форме.

  • Необязательные параметры без соответствующих аргументов удаляются из списка параметров

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

И дальше...

Если последовательности типов параметров {P1, P2, …, PN} и {Q1, Q2, …, QN} эквивалентны> (т. Е. Каждый Pi имеет преобразование идентичности в соответствующую Qi), применяются следующие правила разрыва связи Для того, чтобы определить лучший член функции.

  • Если MP - неуниверсальный метод, а MQ - универсальный метод, то MP лучше, чем MQ.

  • В противном случае, если MP применим в своей нормальной форме, а MQ имеет массив параметров и применим только в расширенной форме, то MP лучше, чем MQ.

  • В противном случае, если MP имеет больше заявленных параметров, чем MQ, то MP лучше, чем MQ. Это может произойти, если оба метода имеют массивы параметров и применимы только в их развернутых формах.

Кажется, что в этом случае применяется правило разрыва жирных связей. В спецификации подробно описывается, как обрабатываются массивы params в нормальной и расширенной формах, но в конечном итоге практическое правило заключается в том, что наиболее специфическая перегрузка будет вызываться с точки зрения количества и типа параметров.

Во-вторых, компилятор сначала попытается выполнить сопоставление с явно объявленными параметрами, а затем обратится к коллекции параметров.

Эта перегрузка хитрая...

MyCoolMethod("Привет", "тест"), очевидно, вызывает 2-ю перегрузку, но

MyCoolMethod("Привет"); также вызывает 2-ю перегрузку. Я проверял это.

Возможно, поскольку оба входа являются объектами, компилятор предполагает, что все, что передается, будет массивом объектов и полностью игнорирует первую перегрузку.

Вероятно, это связано с разрешением элемента Better, упомянутым в womp http://msdn.microsoft.com/en-us/library/aa691338(v=VS.71).aspx

Другие вопросы по тегам