Ответ 1
Да, это было бы лучше , если бы вы не указали , как указывали другие. Для тех, кто интересуется обоснованием отсутствия значений параметров по умолчанию, см. Объяснение @Giovanni Galbo.$
на имена параметров
Верно ли, что единственный способ обработки аргументов функции по умолчанию - перегрузка функций?
Например, в PHP я могу это сделать:
function foo($x, $y=0)
{
}
Будет ли лучший способ справиться с этим в С#?
void foo(int x)
{
foo(x, 0);
}
void foo(int x, int y)
{
}
Изменить
Сделал пример С# в фактическом С# (спасибо Блэру Конраду)
Да, это было бы лучше , если бы вы не указали , как указывали другие. Для тех, кто интересуется обоснованием отсутствия значений параметров по умолчанию, см. Объяснение @Giovanni Galbo.$
на имена параметров
Просто чтобы удовлетворить любопытство:
От Почему С# не поддерживает параметры по умолчанию?:
В таких языках, как С++, значение по умолчанию может быть включено как часть объявления метода:
void Process (Employee employee, bool bonus = false)
Этот метод можно вызвать либо с помощью
a.Process(employee, true);
или
a.Process(сотрудник);
во втором случае бонус параметра установлен в значение false.
С# не имеет этой функции.
Одна из причин, почему у нас нет этой функции, связана с конкретной реализацией функции. В мире С++, когда пользователь пишет:
a.Process(сотрудник);
компилятор генерирует
a.process(employee, false);
Другими словами, компилятор принимает значение по умолчанию, указанное в прототипе метода, и помещает его в вызов метода - он точно так же, как если бы пользователь написал "false" в качестве второго параметра. Невозможно изменить это значение по умолчанию, не заставляя пользователя класса перекомпилировать, что является неудачным.
В этом отношении модель перегрузки работает лучше. Автор структуры просто определяет два отдельных метода, и однопараметрический метод вызывает двухпараметрический метод. Это сохраняет значение по умолчанию в структуре, где оно может быть изменено при необходимости.
Было бы возможно, чтобы компилятор взял что-то вроде определения С++ и произвел перегрузки, но есть несколько проблем с этим подходом.
Первая заключается в том, что корреляция между кодом, который пользователь пишет, и кодом, который генерирует компилятор, менее очевидна. Обычно мы стараемся ограничить магию, когда это возможно, так как это затрудняет программистам. Вторая проблема связана с такими вещами, как комментарии XML doc и intellisense. У компилятора должны быть специальные правила для того, как он генерирует комментарии к документам для перегруженных методов, а intellisense должен иметь smarts для свертывания перегруженных методов в один метод.
Написание перегрузок - это немного менее удобно, но мы считаем это приемлемым решением.
Относительно отрывок из С# faq:
Большинство проблем, перечисленных там, были решены для VB.Net(в частности, проблем с intellisense и xml-комментариями), что означает, что они действительно красные сельди - есть код, доступный команде С#, которая решит проблему.
Другая причина связана с принуждением пользователя к повторной компиляции класса, но это тоже красная селедка. Если вы измените значение по умолчанию в своем классе инфраструктуры и пользователь не должен перекомпилировать, вы рискуете, что пользователь не будет знать, что значение по умолчанию изменилось. Теперь у вас есть потенциальная ошибка в коде, который не отображается до выполнения. Другими словами, альтернатива перегрузки функции, по крайней мере, такая же плохая. Конечно, это также предполагает конкретную реализацию функции, но это реализация, предложенная в faq.
Поэтому вы должны взвесить оставшуюся причину ( "попытаться ограничить магию" ) и факт (который они признают), что запись перегрузок "немного менее удобна". Лично я говорю о включении функции, и пусть программист решил, использовать ее или нет.
Аргументы по умолчанию являются частью С++, но по умолчанию аргументы по умолчанию С# 3.5 по-прежнему не поддерживаются - вам придется перегружать. Они доступны в версии VB.Net с версии 1.0.
Да.
Или каррирование.
Или абстрагироваться в класс и использовать значения по умолчанию.
Нет, AFAIK С# не поддерживает переопределение, и да, это рекомендуемый способ достижения того же эффекта.
Это не делает работу?
void foo(int x):this(x, 0){}
void foo(int x, int y){
// code here
}
Как уже указывалось, в С# это не доступно в настоящее время, но они будут присутствовать в С# 4.0, поскольку Sam Ng обсуждает в своем блоге: