Является ли перегрузка единственным способом иметь аргументы функции по умолчанию в C#?
-
09-06-2019 - |
Вопрос
Правда ли, что единственный способ обработки аргументов функции по умолчанию — это перегрузка функции?
Например, в PHP я могу сделать это:
function foo($x, $y=0)
{
}
Будет ли лучший способ справиться с этим на С#?
void foo(int x)
{
foo(x, 0);
}
void foo(int x, int y)
{
}
Редактировать
Превратил пример C# в настоящий C# (спасибо Блэр Конрад)
Решение
Да, это было бы лучше, за исключением того, что вы опустите , как отмечали другие.Для тех, кто интересуется причиной отсутствия значений параметров по умолчанию, см. объяснение @Giovanni Galbo.$
s в именах параметров
Другие советы
Просто чтобы удовлетворить некоторое любопытство:
От Почему C# не поддерживает параметры по умолчанию?:
В таких языках, как C, значение по умолчанию может быть включено как часть объявления метода:
void Process (сотрудник, бонус bool = false)
Этот метод можно вызвать либо с помощью:
a.Process(сотрудник, правда);
или
а.Процесс(сотрудник);
во втором случае для параметра бонус установлено значение false.
В C# нет этой функции.
Одна из причин, по которой у нас нет этой функции, связана с конкретной реализацией этой функции.В мире C, когда пользователь пишет:
а.Процесс(сотрудник);
компилятор генерирует
a.process(сотрудник, ложь);
Другими словами, компилятор берет значение по умолчанию, указанное в прототипе метода, и помещает его в вызов метода — это точно так же, как если бы пользователь написал «false» в качестве второго параметра.Невозможно изменить это значение по умолчанию, не заставляя пользователя класса перекомпилировать, что прискорбно.
Модель перегрузки в этом отношении работает лучше.Автор фреймворка просто определяет два отдельных метода, а метод с одним параметром вызывает метод с двумя параметрами.При этом значение по умолчанию сохраняется в платформе, где его можно изменить при необходимости.
Компилятор мог бы взять что-то вроде определения C и создать перегрузки, но у этого подхода есть несколько проблем.
Во-первых, корреляция между кодом, который пишет пользователь, и кодом, который генерирует компилятор, менее очевидна.Обычно мы стараемся ограничить магию, когда это возможно, поскольку это усложняет работу программистам.Вторая проблема связана с такими вещами, как комментарии к XML-документам и IntelliSense.У компилятора должны быть специальные правила для создания комментариев к документации для перегруженных методов, а intellisense потребуется сообразительность, чтобы объединить перегруженные методы в один метод.
Писать перегрузки самостоятельно немного менее удобно, но мы считаем это приемлемым решением.
Взяв во внимание выдержка из часто задаваемых вопросов по C#:
Большинство перечисленных там проблем были решены для VB.Net (в частности, проблемы с комментариями intellisense и xml), а это означает, что они действительно отвлекают внимание - команде C# доступен код, который решит проблему.
Другая причина связана с принуждением пользователя к перекомпиляции класса, но это тоже отвлекающий маневр.Если вы изменять значение по умолчанию в вашем классе платформы, и пользователь делает нет придется перекомпилировать, вы рискуете пользователем не зная, что значение по умолчанию изменилось. Теперь у вас есть потенциальная ошибка в коде, которая не проявляется до момента выполнения.Другими словами, альтернатива перегрузке функции не менее плоха.Конечно, это также предполагает конкретную реализацию функции, но это реализация, предложенная в FAQ.
Поэтому вам придется взвесить оставшуюся причину («попытаться ограничить магию») и тот факт (который они признают), что написание перегрузок «немного менее удобно».Лично я предлагаю добавить эту функцию, и пусть программист решает, использовать ее или нет.
Аргументы по умолчанию являются частью C , но, начиная с C# 3.5, аргументы по умолчанию все еще не поддерживаются — вам придется перегрузить их.Они доступны в VB.Net с версии 1.0.
Да.
Или карри.
Или абстрагируемся в класс и используем там значения по умолчанию.
Нет, AFAIK C# не поддерживает переопределение, и да, это рекомендуемый способ достижения того же эффекта.
Как уже отмечалось, в настоящее время это недоступно в C#, однако они будут присутствовать в C# 4.0, как обсуждает Сэм Нг в своем блоге:
это не делает работу?
void foo(int x):this(x, 0){}
void foo(int x, int y){
// code here
}