Давным-давно я много программировал в ADA, и было нормально называть аргументы при вызове функции - SomeObject.DoSomething (SomeParameterName => someValue);
Теперь, когда C # поддерживает именованные аргументы, я думаю о том, чтобы вернуться к этой привычке в ситуациях, когда может быть не очевидно, что означает аргумент.
Вы можете утверждать, что всегда должно быть очевидно, что означает аргумент, но если у вас есть логический аргумент, и вызывающие абоненты передают «true» или «false», то квалификация значения с именем делает сайт вызова более читабельным.
contentFetcher.DownloadNote (примечание, руководство: правда);
Думаю, я мог бы создать Enums вместо использования true или false (в данном случае Manual, Automatic).
Что вы думаете о том, чтобы иногда использовать именованные аргументы для облегчения чтения кода?
источник
Ответы:
Это было предложено при разработке C ++, и Страуструп обсуждает это в своей статье «Проектирование и развитие C ++», стр. 153 и далее. Предложение было правильно сформулировано и основано на предыдущем опыте работы с Ada. Это не было принято.
Основной причиной было то, что никто не хотел поощрять функции с большим количеством параметров. Каждая дополнительная функция в языке чего-то стоит, и не было желания добавлять функцию, чтобы было легче писать плохие программы.
Также были подняты вопросы о том, что представляют собой канонические имена параметров, особенно в обычном соглашении заголовка и файла кода. Некоторые организации имели более длинные и более описательные имена параметров в файле .h, а также более короткие и удобные для ввода имен в файле .cpp (заменяйте суффиксы файлов по желанию). Требование, чтобы они были одинаковыми, потребовало бы дополнительных затрат на компиляцию, а перепутывание имен в исходных файлах может привести к незначительным ошибкам.
Это также может быть обработано с помощью объектов, а не вызовов функций. Вместо вызова GetWindow с дюжиной параметров создайте класс Window с дюжиной личных переменных и при необходимости добавьте установщики. Сцепляя сеттеры, можно написать что-то вроде
my_window.SetColor(green).SetBorder(true).SetBorderSize(3);
. Также возможно иметь разные функции с разными значениями по умолчанию, которые вызывают функцию, которая фактически выполняет эту работу.Если вы просто беспокоитесь о влиянии документации
contentFetcher.DownloadNote(note, manual : true);
, вы всегда можете написать что-то вроде этогоcontentFetcher.DownloadNote(note, /* manual */ true);
, так что это не очень полезно в документации.источник
Я думаю, что проблема заключается в том, чтобы сделать плохой код более читабельным, а не в «лучшей практике».
Наличие метода (или подрядчика), который принимает 20 параметров, является «неприятным запахом» и может быть связано с проблемой в вашем дизайне. Однако если я вынужден работать над кодом, когда методы принимают много параметров, то именованный параметр делает код менее трудным для понимания.
Если у методов есть только 1 или 2 параметра, и из имени метода ясно, что это за параметр, то именованный параметр ничего не добавляет. Это идеальный случай.
Если весь код, над которым вы работаете, написан в соответствии с книгой « чистого кода », то вы будете очень мало использовать для именованных параметров, однако мы живем в реальном мире.
источник
void TrackDataChange(Data oldData, Data newData)
Я согласен, что добавление имени параметра делает его более читабельным. Тем не менее, большинство книг, которые я прочитал, похоже, считают булевы переключатели плохой практикой. Я иногда делаю это:
Это дает вам больше гибкости при реализации вашего API. Это также позволяет вам контролировать случай, когда у вас есть несколько логических переключателей, но не все из них могут быть активными одновременно.
источник
Я большой сторонник именованных параметров в ситуациях, когда типы и семантика не понятны из названия метода. Мой опыт показывает, что мало кто читает документацию.
При этом именованные параметры не должны быть альтернативой созданию разумных списков аргументов, использованию вспомогательных объектов (для «связывания» семантически связанных аргументов) и использования перечислений, где это уместно.
источник
Я думаю, что это более полезно в не OO-языках, где у вас может быть одна функция, которая должна что-то делать несколькими различными способами, и способ ее определения зависит от значений параметров. В мире ООП мы просто перегружаем функцию, но когда это невозможно, вы в итоге передаете набор флагов (или набор значений, и независимо от того, переданы они или нет, является флагом).
Я думаю, что это более читабельно, в некоторой степени; но, как уже упоминали другие, наличие большого количества параметров является запахом кода, поэтому я не вижу большой пользы для этого в объектно-ориентированном языке, таком как C #.
источник