Конфликт перегруженных методов с необязательными параметрами - PullRequest
24 голосов
/ 20 апреля 2010

У меня есть два перегруженных метода, один с необязательным параметром.

void foo(string a)  { }  
void foo(string a, int b = 0) { }  

Теперь я звоню:

 foo("abc");

Интересно, первая перегрузка называется.почему бы не вторая перегрузка с необязательным значением, равным нулю?

Если честно, я бы ожидал, что компилятор выдаст ошибку, по крайней мере, предупреждение, чтобы избежать непреднамеренного выполнения неправильного метода.

В чем причина такого поведения?Почему команда C # определила это так?

Ответы [ 3 ]

32 голосов
/ 20 апреля 2010

С MSDN :

Если два кандидата признаны одинаково хорошими, предпочтение отдается кандидату, у которого нет дополнительных параметров, аргументы которых были опущены в вызове. Это является следствием общего предпочтения в разрешении перегрузки для кандидатов, у которых меньше параметров.

14 голосов
/ 20 апреля 2010

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

void Foo(int x, int y = 0, int z = 0) {}
void Foo(int x, int y = 0) {}
...
Foo(5);

Обратите внимание, что Foo (5, 5) будет преобразован во второй метод, потому что тогда он не требует автоматического заполнения каких-либо дополнительных параметров.

Из раздела 7.5.3.2 спецификации C # 4:

В противном случае, если все параметры МП имеют соответствующий аргумент, тогда как аргументы по умолчанию должны быть заменить по крайней мере один необязательный параметр в MQ, то MP лучше, чем MQ.

Я думаю, что в большинстве случаев такое поведение ожидают большинство людей, если честно. Странно, когда вы вводите в базовый класс методы, но так было всегда.

7 голосов
/ 22 апреля 2010

Представьте, если бы это было наоборот. У вас было заявление. У него был метод:

void foo(string a)  { }   

Все работало нормально. Теперь вы хотите добавить еще одну перегрузку с необязательным параметром:

void foo(string a, int b = 0) { }  

Boom! Все вызовы метода переходят к новому методу. Когда вы этого хотите или нет. Добавление перегрузки метода может привести к неправильным вызовам методов во всем приложении.

С моей точки зрения, в этом случае у вас будет гораздо больше возможностей нарушить ваш (или чужой) код.

Кроме того, OptionalAttribute игнорировался в C # до версии 4.0, но вы могли использовать его. И некоторые люди использовали его в коде C # для поддержки определенных сценариев взаимодействия с другими языками, такими как Visual Basic или для взаимодействия COM. Теперь C # использует его для необязательных параметров. Добавление предупреждений / ошибок может привести к серьезным изменениям в этих приложениях.

Могут быть и другие причины, но это первое, что приходит мне в голову.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...