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

StackOverflow https://stackoverflow.com/questions/40090

  •  09-06-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

void foo(int x, int y)
{
}

Пример взят отсюда

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

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

Это было полезно?

Решение

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

Другие советы

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

От Почему 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, как обсуждает Сэм Нг в своем блоге:

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

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

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

void foo(int x, int y){
 // code here
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top