Есть моменты, когда мне нужно изменить значение, переданное в метод изнутри самого метода. Примером может служить очистка строки, такой как этот метод, здесь:
void SanitizeName(string Name)
{
Name = Name.ToUpper();
//now do something here with name
}
Это чисто безвредно, поскольку Name
аргумент не передается по ссылке. Однако, если по какой-либо причине разработчик в будущем решит передать все значения по ссылке, любая очистка строки повлияет на значение вне метода, что может привести к отрицательным результатам.
Поэтому вместо переназначения самого аргумента я всегда создаю локальную копию следующим образом:
void SanitizeName(string Name)
{
var SanitizedName = Name.ToUpper();
//now do something here with name
}
Это гарантирует, что изменение значения, в которое передается значение, никогда не повлияет на действия вне метода, но мне интересно, насколько я чрезмерно параноидален в этом.
design
programming-practices
oscilatingcretin
источник
источник
Name = Name.ToUpper();
делает код труднее следовать в вашей голове, как значениеName
изменений. Ваш второй пример не только более ориентирован на будущее, но и легче рассуждать о том, что он делает.if (param == NULL) param = default_value;
?by ref
которое не было передано, Заранее, и поэтому, преобразовывая локальный доступ в нелокальный доступ по какой-то причине, он всегда должен тщательно проверять последствия.Ответы:
Я думаю, что это зависит от ваших правил кодирования в вашем проекте.
Я лично позволил eclipse автоматически добавлять
final
ключевое слово в каждую переменную и параметр. Таким образом, вы видите на первый взгляд, если параметр используется повторно.В проекте на моей работе мы не рекомендуем повторно использовать параметры, но если вы просто хотите вызвать, например,
.trim()
или установить значение по умолчанию вnull
случае, мы используем параметр большую часть времени, потому что введение новой переменной в таких случаях менее читабельно чем повторное использование параметра.Вы действительно не должны повторно использовать параметр для хранения совершенно другого контента, потому что имя больше не будет ссылаться на его контент. Но это верно для каждой переназначения переменной и не ограничивается параметрами.
Так что соберитесь со своей командой и сформулируйте соглашения по кодированию, которые охватывают этот вопрос.
источник
Если вы используете статический анализатор кода в целях безопасности, он может запутаться и подумать, что вы не проверяли и не очищали переменную входного параметра перед использованием.
Name
Например, если вы используете SQL-запрос, он может претендовать на уязвимость SQL-инъекции, что обойдется вам в объяснениях. Это плохо. С другой стороны, использование переменной с четким именем для очищенного ввода без фактической очистки ввода - это быстрый способ успокоить наивные анализаторы кода (ложноотрицательный поиск уязвимостей).источник
Ответ на это зависит на 100% от того, кто будет читать ваш код. Какие стили они находят наиболее полезными?
Я обнаружил, что наиболее общий случай состоит в том, что избегают переназначения значений аргументам функций, потому что слишком много разработчиков имеют ментальные модели того, как работает вызов функций, которые предполагают, что вы никогда этого не делаете. Эта проблема может усугубляться отладчиками, которые выводят значения аргументов, которые вы вызываете для каждой функции. Эта информация технически неверна, если вы редактируете аргументы, и это может привести к некоторым странным разочарованиям.
Это сказанное, умственные модели изменяются. В вашей конкретной среде разработки может быть желательно иметь
name
«лучшее представление имени на данный момент». Может быть, желательно более явно связать переменные, над которыми вы работаете, с их аргументами, даже если вы по ходу делали некоторые изменения в их значениях. Могут даже быть существенные преимущества во время выполнения для повторного использования некоторых конкретных переменных вместо создания более громоздких объектов. В конце концов, когда вы работаете со строками 4 ГБ, приятно минимизировать количество дополнительных копий, которые вы должны сделать!источник
У меня совершенно другая проблема с вашим примером кода:
Имя вашего метода является
SanitizeName
. В этом случае я ожидаю, что это очистит имя ; потому что это то, что вы говорите читателю о вашей функции.Только вещь, которую вы работать должны сделать , это дезинфицирующим данное имя . Не читая ваш код, я ожидал бы следующее:
Но вы подразумеваете, что ваш метод делает немного больше, чем только санитарная обработка. Это кодовый запах, и его следует избегать.
Ваш вопрос не о том, является ли плохой практикой повторное использование параметров метода? Больше: вредны ли побочные эффекты и неискаженное поведение?
Ответ на это однозначно: да!
Вы вводите своего читателя в заблуждение, ничего не возвращая. Название вашего метода четко указывает на то, что вы делаете что-то
Name
. Итак, куда должен идти результат? По вашей функции подписьvoid
читает, что я использую,Name
но не причиняю никакого вреда идентификатору и не сообщаю вам о результате (прямо). Возможно, есть исключение, а может и нет; ноName
не изменяется . Это семантическая противоположность имени вашего метода.Проблема заключается не столько в повторном использовании, сколько в побочных эффектах . Для предотвращения побочных эффектов не используйте переменную повторно . Если у вас нет побочных эффектов, нет проблем.
источник