Является ли перегрузка единственным способом иметь аргументы функции по умолчанию в C #? - PullRequest
10 голосов
/ 02 сентября 2008

Правда ли, что единственный способ обработки аргументов функций по умолчанию - перегрузка функций?

Например, в PHP я могу сделать это:

function foo($x, $y=0)
{
}

Будет ли лучший способ справиться с этим в C # так?

void foo(int x)
{
  foo(x, 0);
}

void foo(int x, int y)
{
}

Пример отснятого здесь

Редактировать

Преврати пример C # в реальный C # (спасибо Блэр Конрад)

Ответы [ 8 ]

20 голосов
/ 02 сентября 2008

Просто чтобы удовлетворить любопытство:

С Почему C # не поддерживает параметры по умолчанию? :

В таких языках, как C ++, значение по умолчанию может быть включено как часть объявления метода:

void Process (Сотрудник сотрудника, бонус bool = false)

Этот метод можно вызвать с помощью:

a.Process (сотрудник, верно);

или

a.Process (работник);

во втором случае для параметра бонус устанавливается значение false.

C # не имеет этой функции.

Одна из причин, по которой у нас нет этой функции, связана с конкретной реализацией функции. В мире C ++, когда пользователь пишет:

a.Process (работник);

компилятор генерирует

a.process (сотрудник, ложь);

Другими словами, компилятор принимает значение по умолчанию, указанное в прототипе метода, и помещает его в вызов метода - это так же, как если бы пользователь написал «false» в качестве второго параметра. Нет никакого способа изменить это значение по умолчанию, не заставляя пользователя класса перекомпилировать, что является неудачным.

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

Компилятор мог бы взять что-то вроде определения C ++ и создать перегрузки, но с этим подходом есть несколько проблем.

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

Писать перегрузки немного менее удобно, но мы думаем, что это приемлемое решение.

5 голосов
/ 02 сентября 2008

Да, это будет лучше , за исключением того, что вы пропустите $ s в именах параметров , как указали другие. Для тех, кто заинтересован в обосновании отсутствия значений параметров по умолчанию, см. Объяснение @Giovanni Galbo.

4 голосов
/ 02 сентября 2008

Относительно выдержки из c # faq :

Большинство проблем, перечисленных там, были решены для VB.Net (в частности, проблемы с intellisense и xml-комментариями), что означает, что они действительно являются «красными сельдями» - есть команда, доступная команде C #, которая решит проблему .

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

Поэтому вы должны взвесить оставшуюся причину («попытаться ограничить магию») против того факта (который они признают), что запись перегрузок «немного менее удобна». Лично я говорю: включите эту функцию и позвольте программисту решить, использовать ее или нет.

2 голосов
/ 02 сентября 2008

Аргументы по умолчанию являются частью C ++, но в C # 3.5 аргументы по умолчанию все еще не поддерживаются - вам придется перегружать. Они доступны в VB.Net с 1.0.

0 голосов
/ 30 марта 2009

Как указано, в настоящее время это недоступно в C #, однако они будут присутствовать в C # 4.0, как Сэм Нг обсуждает в своем блоге:

http://blogs.msdn.com/samng/archive/2009/02/03/named-arguments-optional-arguments-and-default-values.aspx

0 голосов
/ 30 марта 2009

разве это не делает работу?

void foo(int x):this(x, 0){}

void foo(int x, int y){
 // code here
}
0 голосов
/ 02 сентября 2008

Нет, AFAIK C # не поддерживает переопределение, и да, это рекомендуемый способ достижения того же эффекта.

0 голосов
/ 02 сентября 2008

Да.

Или карри.

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

...