Конфликтующие перегруженные методы с дополнительными параметрами

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

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

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

 foo("abc");

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

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

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

24
задан user247702 11 August 2014 в 11:51
поделиться

3 ответа

Из MSDN:

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

32
ответ дан 28 November 2019 в 23:05
поделиться

Только представьте, было бы наоборот. У вас была заявка. У него был метод:

void foo(string a)  { }   

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

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

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

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

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

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

7
ответ дан 28 November 2019 в 23:05
поделиться

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

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:

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

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

14
ответ дан 28 November 2019 в 23:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: