Чи погана практика використовувати параметри методу?


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" , я, мабуть, маю аргумент із цим розробником, повторним використанням параметрів чи ні ;-) Чесно кажучи, коли хто вирішить передати значення, by refяке не було передано, заздалегідь, і тому перетворюючи локальний доступ на немісцевий доступ з якоїсь причини, він завжди повинен ретельно перевіряти наслідки.
Doc Brown

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, ви випадково працюєте з посиланням замість копії, це викликає побічні ефекти (як я вже сказав), і це погано. Щоб уникнути цього, вказуйте на те, що ви збираєтесь змінити змінну, обережно вибираючи ім'я методу (подумайте про «Рубі»! Якщо ви не змінюєте змінну, працюйте лише з копіями.
Thomas Junk
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.