Следующий код компилирует в C# 4.0:
void Foo(params string[] parameters) { }
void Foo(string firstParameter, params string[] parameters) { }
Как компилятор знает, какую перегрузку Вы называете? И если это не может, почему код все еще компилирует?
Это хорошо указано в Спецификации языка C #, глава 7.4.3.2, «Лучшая функция-член»:
В противном случае, если MP применим в его нормальной форме и MQ имеет массив параметров и применимо только в его расширенной форме, тогда MP лучше, чем MQ
. В противном случае, если MP имеет меньше заявленных параметров, чем MQ, тогда MP лучше, чем MQ. Это может произойти, если оба метода имеют массивы параметров и применимы только в их развернутых формах.
Фвив, Спецификация языка C # - это очень читаемый документ, который может помочь вам решить эти головоломки самостоятельно. У вас он есть на вашем компьютере, найдите его в каталоге установки Visual Studio (например, c: \ program files \ microsoft visual studio 9.0) в подкаталоге vc # \ specs \ 1033.
Еще один хороший документ - это стандартный документ Ecma-335, свободно доступный в виде PDF для загрузки . Он определяет поведение CLR и JIT-компилятора, отличный материал для понимания того, почему C # (и CLR) делают то, что они делают. Рекомендуемые.
В некоторых случаях он будет решать за вас. Поэтому в подобных случаях (или в более полезных случаях :-) ) вы, возможно, захотите использовать другие имена.
В частности, из четырех случаев:
Foo("bar");
Foo("bar", "bar");
Foo(new string[]{"bar", "bar"});
Foo("bar", new string[] { "bar", "bar" });
только #1 и #2 являются "неоднозначными" (поскольку #3 и #4 естественно соответствуют перегрузке 1 и 2 соответственно).
В случаях #1 и #2 разрешение перегрузки выбирает перегрузку #2, потому что у нее есть отдельный строковый параметр, который совпадает с единственным/первым параметром вызова.