Это плохая практика, чтобы повторно использовать параметры метода?


12

Есть моменты, когда мне нужно изменить значение, переданное в метод изнутри самого метода. Примером может служить очистка строки, такой как этот метод, здесь:

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
}

Это гарантирует, что изменение значения, в которое передается значение, никогда не повлияет на действия вне метода, но мне интересно, насколько я чрезмерно параноидален в этом.


1
Да, это плохая практика; и нет, это не безопасно. Строка Name = Name.ToUpper();делает код труднее следовать в вашей голове, как значение Nameизменений. Ваш второй пример не только более ориентирован на будущее, но и легче рассуждать о том, что он делает.
Дэвид Арно,

2
Но как насчет if (param == NULL) param = default_value;?
aragaer

Я думаю, что это не так просто, как да / нет.
MrSmith42

3
Если «разработчик в будущем решит передать все значения через ref» , я бы, вероятно, имел аргумент с этим dev, задействовано ли повторное использование параметра ;-) Честно говоря, когда кто-то решает передать значение, by refкоторое не было передано, Заранее, и поэтому, преобразовывая локальный доступ в нелокальный доступ по какой-то причине, он всегда должен тщательно проверять последствия.
Док Браун

2
Я в первую очередь работать в парадигме , где мы никогда не переназначить любые переменные. Когда-либо. Забавно представить, что кто-то борется с тем, должны ли они переназначать небольшое количество переменных, а затем не беспокоиться о том, чтобы сойти с ума с остальными.
Карл Билефельдт

Ответы:


10

Я думаю, что это зависит от ваших правил кодирования в вашем проекте.

Я лично позволил eclipse автоматически добавлять finalключевое слово в каждую переменную и параметр. Таким образом, вы видите на первый взгляд, если параметр используется повторно.

В проекте на моей работе мы не рекомендуем повторно использовать параметры, но если вы просто хотите вызвать, например, .trim()или установить значение по умолчанию в nullслучае, мы используем параметр большую часть времени, потому что введение новой переменной в таких случаях менее читабельно чем повторное использование параметра.

Вы действительно не должны повторно использовать параметр для хранения совершенно другого контента, потому что имя больше не будет ссылаться на его контент. Но это верно для каждой переназначения переменной и не ограничивается параметрами.

Так что соберитесь со своей командой и сформулируйте соглашения по кодированию, которые охватывают этот вопрос.


0

Если вы используете статический анализатор кода в целях безопасности, он может запутаться и подумать, что вы не проверяли и не очищали переменную входного параметра перед использованием. NameНапример, если вы используете SQL-запрос, он может претендовать на уязвимость SQL-инъекции, что обойдется вам в объяснениях. Это плохо. С другой стороны, использование переменной с четким именем для очищенного ввода без фактической очистки ввода - это быстрый способ успокоить наивные анализаторы кода (ложноотрицательный поиск уязвимостей).


В большинстве случаев вы также можете использовать какую-то аннотацию или специальный комментарий, чтобы указать анализатору кода, что это подразумевается, а не остается незамеченным.
MrSmith42

0

Ответ на это зависит на 100% от того, кто будет читать ваш код. Какие стили они находят наиболее полезными?

Я обнаружил, что наиболее общий случай состоит в том, что избегают переназначения значений аргументам функций, потому что слишком много разработчиков имеют ментальные модели того, как работает вызов функций, которые предполагают, что вы никогда этого не делаете. Эта проблема может усугубляться отладчиками, которые выводят значения аргументов, которые вы вызываете для каждой функции. Эта информация технически неверна, если вы редактируете аргументы, и это может привести к некоторым странным разочарованиям.

Это сказанное, умственные модели изменяются. В вашей конкретной среде разработки может быть желательно иметь name«лучшее представление имени на данный момент». Может быть, желательно более явно связать переменные, над которыми вы работаете, с их аргументами, даже если вы по ходу делали некоторые изменения в их значениях. Могут даже быть существенные преимущества во время выполнения для повторного использования некоторых конкретных переменных вместо создания более громоздких объектов. В конце концов, когда вы работаете со строками 4 ГБ, приятно минимизировать количество дополнительных копий, которые вы должны сделать!


-1

У меня совершенно другая проблема с вашим примером кода:

Имя вашего метода является SanitizeName. В этом случае я ожидаю, что это очистит имя ; потому что это то, что вы говорите читателю о вашей функции.

Только вещь, которую вы работать должны сделать , это дезинфицирующим данное имя . Не читая ваш код, я ожидал бы следующее:

string SanitizeName(string Name)
{
    //somehow sanitize the name
    return Result;
}

Но вы подразумеваете, что ваш метод делает немного больше, чем только санитарная обработка. Это кодовый запах, и его следует избегать.

Ваш вопрос не о том, является ли плохой практикой повторное использование параметров метода? Больше: вредны ли побочные эффекты и неискаженное поведение?

Ответ на это однозначно: да!

Это чисто безвредно, поскольку аргумент Name не передается по ссылке. Однако, если по какой-либо причине разработчик в будущем решит передать все значения по ссылке, любая очистка строки повлияет на значение вне метода, что может привести к отрицательным результатам.

Вы вводите своего читателя в заблуждение, ничего не возвращая. Название вашего метода четко указывает на то, что вы делаете что-то Name. Итак, куда должен идти результат? По вашей функции подпись voidчитает, что я использую, Nameно не причиняю никакого вреда идентификатору и не сообщаю вам о результате (прямо). Возможно, есть исключение, а может и нет; но Nameне изменяется . Это семантическая противоположность имени вашего метода.

Проблема заключается не столько в повторном использовании, сколько в побочных эффектах . Для предотвращения побочных эффектов не используйте переменную повторно . Если у вас нет побочных эффектов, нет проблем.


4
-1 Это не отвечает на оригинальный вопрос. Предоставленный код является просто примером кода для показа вопроса под рукой. Пожалуйста, ответьте на вопрос, вместо того чтобы «атаковать» / просматривать предоставленный пример кода.
Никлас Х

1
@NiklasH Это прекрасно отвечает на вопрос: если вы манипулируете параметром внутри функции и, как упоминалось в TO, вы случайно работаете со ссылкой, а не с копией, это вызывает побочные эффекты (как я уже говорил), и это плохо. Чтобы предотвратить это, укажите, что вы собираетесь изменить переменную, тщательно выбрав имя метода (подумайте о '!' В Ruby) и / или выбрав тип возвращаемого значения. Если вы не изменяете переменную, работайте только с копиями.
Томас Джанк
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.