Подтвердить что ты не робот

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

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

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

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

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

MyCoolMethod("Hi", "test");

который вызывается и почему?

4b9b3361

Ответ 1

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

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

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

7.5.3.2 Более эффективный член функции

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

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

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

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

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

И далее...

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

  • Если MP - это не общий метод, а MQ - общий метод, то MP лучше, чем MQ.

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

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

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

Ответ 2

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

Ответ 3

Эта перегрузка сложна...

MyCoolMethod ( "Hi", "test" ), очевидно, вызывает вторую перегрузку, но

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

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

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